From 6c6a334f0aa3b95572afe30fa2d17e634c7019ce Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Fri, 1 Jan 2021 03:04:10 +0000 Subject: CTAN sync 202101010304 --- FILES.byname | 1853 +- FILES.byname.gz | Bin 2251377 -> 2251451 bytes FILES.last07days | 1113 +- biblio/biber/documentation/Changes | 7 + biblio/biber/documentation/biber.pdf | Bin 265333 -> 267307 bytes macros/latex/base/README.md | 2 +- macros/latex/base/alltt.pdf | Bin 173079 -> 173079 bytes macros/latex/base/cfgguide.pdf | Bin 220217 -> 220217 bytes macros/latex/base/changes.txt | 72 + macros/latex/base/classes.pdf | Bin 520851 -> 520851 bytes macros/latex/base/clsguide.pdf | Bin 372555 -> 372555 bytes macros/latex/base/cmfonts.pdf | Bin 264505 -> 264505 bytes macros/latex/base/cyrguide.pdf | Bin 216997 -> 216997 bytes macros/latex/base/doc.pdf | Bin 630922 -> 631201 bytes macros/latex/base/docstrip.pdf | Bin 479544 -> 479501 bytes macros/latex/base/encguide.pdf | Bin 1532144 -> 1532144 bytes macros/latex/base/exscale.pdf | Bin 195877 -> 195877 bytes macros/latex/base/fix-cm.pdf | Bin 262059 -> 262059 bytes macros/latex/base/fntguide.pdf | Bin 417861 -> 418342 bytes macros/latex/base/fntguide.tex | 16 +- macros/latex/base/graphpap.pdf | Bin 156277 -> 156277 bytes macros/latex/base/ifthen.pdf | Bin 205213 -> 205213 bytes macros/latex/base/inputenc.pdf | Bin 294900 -> 294900 bytes macros/latex/base/latexchanges.pdf | Bin 232390 -> 232390 bytes macros/latex/base/latexrelease.ins | 48 +- macros/latex/base/latexrelease.pdf | Bin 246195 -> 246195 bytes macros/latex/base/latexsym.pdf | Bin 192297 -> 192297 bytes macros/latex/base/lb2.pdf | Bin 138219 -> 138219 bytes macros/latex/base/letter.pdf | Bin 305700 -> 305786 bytes macros/latex/base/lgc2.pdf | Bin 101343 -> 101343 bytes macros/latex/base/lppl.pdf | Bin 125830 -> 125830 bytes macros/latex/base/ltclass.dtx | 200 +- macros/latex/base/ltdefns.dtx | 13 +- macros/latex/base/ltexpl.dtx | 123 +- macros/latex/base/ltfilehook-code.pdf | Bin 735464 -> 744388 bytes macros/latex/base/ltfilehook-doc.pdf | Bin 516397 -> 516587 bytes macros/latex/base/ltfilehook.dtx | 174 +- macros/latex/base/ltfssaxes.dtx | 2 +- macros/latex/base/ltfssbas.dtx | 23 +- macros/latex/base/lthooks-code.pdf | Bin 901929 -> 926391 bytes macros/latex/base/lthooks-doc.pdf | Bin 621088 -> 626854 bytes macros/latex/base/lthooks.dtx | 830 +- macros/latex/base/ltluatex.pdf | Bin 305339 -> 305339 bytes macros/latex/base/ltmath.dtx | 9 +- macros/latex/base/ltmiscen.dtx | 15 +- macros/latex/base/ltnews.pdf | Bin 989398 -> 989398 bytes macros/latex/base/ltnews01.pdf | Bin 150020 -> 150020 bytes macros/latex/base/ltnews02.pdf | Bin 134751 -> 134751 bytes macros/latex/base/ltnews03.pdf | Bin 134742 -> 134742 bytes macros/latex/base/ltnews04.pdf | Bin 128772 -> 128772 bytes macros/latex/base/ltnews05.pdf | Bin 157181 -> 157181 bytes macros/latex/base/ltnews06.pdf | Bin 133138 -> 133138 bytes macros/latex/base/ltnews07.pdf | Bin 124029 -> 124029 bytes macros/latex/base/ltnews08.pdf | Bin 144482 -> 144482 bytes macros/latex/base/ltnews09.pdf | Bin 120222 -> 120222 bytes macros/latex/base/ltnews10.pdf | Bin 147946 -> 147946 bytes macros/latex/base/ltnews11.pdf | Bin 104936 -> 104936 bytes macros/latex/base/ltnews12.pdf | Bin 137919 -> 137919 bytes macros/latex/base/ltnews13.pdf | Bin 161065 -> 161065 bytes macros/latex/base/ltnews14.pdf | Bin 150907 -> 150907 bytes macros/latex/base/ltnews15.pdf | Bin 122092 -> 122092 bytes macros/latex/base/ltnews16.pdf | Bin 130687 -> 130687 bytes macros/latex/base/ltnews17.pdf | Bin 149838 -> 149838 bytes macros/latex/base/ltnews18.pdf | Bin 36005 -> 36005 bytes macros/latex/base/ltnews19.pdf | Bin 235073 -> 235073 bytes macros/latex/base/ltnews20.pdf | Bin 283318 -> 283318 bytes macros/latex/base/ltnews21.pdf | Bin 233492 -> 233492 bytes macros/latex/base/ltnews22.pdf | Bin 302836 -> 302836 bytes macros/latex/base/ltnews23.pdf | Bin 274459 -> 274459 bytes macros/latex/base/ltnews24.pdf | Bin 252645 -> 252645 bytes macros/latex/base/ltnews25.pdf | Bin 196326 -> 196326 bytes macros/latex/base/ltnews26.pdf | Bin 362839 -> 362839 bytes macros/latex/base/ltnews27.pdf | Bin 239758 -> 239758 bytes macros/latex/base/ltnews28.pdf | Bin 368226 -> 368226 bytes macros/latex/base/ltnews29.pdf | Bin 433004 -> 433004 bytes macros/latex/base/ltnews30.pdf | Bin 491246 -> 491246 bytes macros/latex/base/ltnews31.pdf | Bin 500919 -> 500919 bytes macros/latex/base/ltnews32.pdf | Bin 520923 -> 520923 bytes macros/latex/base/ltshipout-code.pdf | Bin 749471 -> 750748 bytes macros/latex/base/ltshipout-doc.pdf | Bin 503979 -> 503965 bytes macros/latex/base/ltshipout.dtx | 22 +- macros/latex/base/ltvers.dtx | 2 +- macros/latex/base/ltx3info.pdf | Bin 191527 -> 191527 bytes macros/latex/base/ltxdoc.pdf | Bin 215102 -> 215102 bytes macros/latex/base/makeindx.pdf | Bin 160667 -> 160667 bytes macros/latex/base/manual.pdf | Bin 151347 -> 151347 bytes macros/latex/base/modguide.pdf | Bin 220388 -> 220388 bytes macros/latex/base/nfssfont.pdf | Bin 202451 -> 202451 bytes macros/latex/base/proc.pdf | Bin 216877 -> 216877 bytes macros/latex/base/slides.pdf | Bin 351586 -> 351586 bytes macros/latex/base/slifonts.pdf | Bin 214710 -> 214710 bytes macros/latex/base/source2e.pdf | Bin 4349921 -> 4357396 bytes macros/latex/base/source2edoc.cls | 39 +- macros/latex/base/syntonly.pdf | Bin 181390 -> 181787 bytes macros/latex/base/tlc2.pdf | Bin 164947 -> 164947 bytes macros/latex/base/tulm.pdf | Bin 156546 -> 156546 bytes macros/latex/base/usrguide.pdf | Bin 399035 -> 399035 bytes macros/latex/base/utf8ienc.pdf | Bin 330853 -> 331074 bytes macros/latex/base/webcomp.pdf | Bin 136159 -> 136159 bytes macros/latex/contrib/biblatex/CHANGES.md | 26 +- .../latex/contrib/biblatex/bibtex/bst/biblatex.bst | 2 +- macros/latex/contrib/biblatex/doc/biblatex.pdf | Bin 1588759 -> 1598244 bytes macros/latex/contrib/biblatex/doc/biblatex.tex | 128 +- .../doc/examples/03-localization-keys-biber.pdf | Bin 246343 -> 246067 bytes .../doc/examples/03-localization-keys-bibtex.pdf | Bin 245414 -> 245466 bytes .../biblatex/doc/examples/03-localization-keys.tex | 2 + .../doc/examples/16-numeric-prefixed-1-bibtex.pdf | Bin 156536 -> 156540 bytes .../doc/examples/16-numeric-prefixed-1-bibtex.tex | 53 - .../doc/examples/17-numeric-prefixed-2-bibtex.pdf | Bin 156527 -> 156540 bytes .../doc/examples/17-numeric-prefixed-2-bibtex.tex | 40 - .../doc/examples/19-alphabetic-prefixed-bibtex.pdf | Bin 157502 -> 157616 bytes .../doc/examples/19-alphabetic-prefixed-bibtex.tex | 44 - .../biblatex/doc/examples/82-style-debug-biber.pdf | Bin 150179 -> 149679 bytes .../biblatex/doc/examples/93-nameparts-biber.pdf | Bin 37768 -> 39823 bytes .../contrib/biblatex/doc/examples/93-nameparts.tex | 19 +- .../contrib/biblatex/doc/examples/96-dates.tex | 3 +- .../biblatex/doc/examples/97-annotations.tex | 3 +- macros/latex/contrib/biblatex/latex/bbx/draft.bbx | 4 + .../latex/contrib/biblatex/latex/bbx/numeric.bbx | 4 + .../latex/contrib/biblatex/latex/bbx/reading.bbx | 4 + .../latex/contrib/biblatex/latex/bbx/standard.bbx | 6 +- macros/latex/contrib/biblatex/latex/biblatex.def | 49 +- macros/latex/contrib/biblatex/latex/biblatex.sty | 398 +- macros/latex/contrib/biblatex/latex/blx-bibtex.def | 10 +- .../contrib/biblatex/latex/blx-case-expl3.def | 271 - .../contrib/biblatex/latex/blx-case-expl3.sty | 289 + .../contrib/biblatex/latex/blx-case-latex2e.def | 290 - .../contrib/biblatex/latex/blx-case-latex2e.sty | 326 + macros/latex/contrib/biblatex/latex/blx-compat.def | 4 + macros/latex/contrib/biblatex/latex/blx-dm.def | 10 +- .../latex/contrib/biblatex/latex/blx-unicode.def | 14 + macros/latex/contrib/biblatex/latex/lbx/basque.lbx | 480 + .../latex/contrib/biblatex/latex/lbx/catalan.lbx | 172 +- .../latex/contrib/biblatex/latex/lbx/english.lbx | 2 + macros/latex/contrib/biblatex/latex/lbx/french.lbx | 18 +- macros/latex/contrib/biblatex/latex/lbx/german.lbx | 2 + macros/luatex/generic/lualibs/NEWS | 3 + macros/luatex/generic/lualibs/README.md | 6 +- .../generic/lualibs/lualibs-basic-merged.lua | 29 +- .../generic/lualibs/lualibs-extended-merged.lua | 6 +- macros/luatex/generic/lualibs/lualibs-os.lua | 2 + macros/luatex/generic/lualibs/lualibs-package.lua | 24 +- macros/luatex/generic/lualibs/lualibs-util-dim.lua | 18 +- macros/luatex/generic/lualibs/lualibs.dtx | 18 +- macros/luatex/generic/lualibs/lualibs.pdf | Bin 81574 -> 81487 bytes macros/luatex/generic/luaotfload/NEWS | 28 +- macros/luatex/generic/luaotfload/README.md | 4 +- macros/luatex/generic/luaotfload/filegraph.pdf | Bin 40015 -> 40030 bytes macros/luatex/generic/luaotfload/filegraph.tex | 2 +- .../generic/luaotfload/fontloader-2020-08-31.lua | 35049 ------------------ .../generic/luaotfload/fontloader-2020-12-30.lua | 35110 +++++++++++++++++++ .../generic/luaotfload/fontloader-basics-nod.lua | 19 + .../generic/luaotfload/fontloader-font-dsp.lua | 2 +- .../luaotfload/fontloader-font-imp-effects.lua | 109 +- .../generic/luaotfload/fontloader-font-one.lua | 19 +- .../generic/luaotfload/fontloader-font-otl.lua | 35 +- .../generic/luaotfload/fontloader-font-ots.lua | 311 +- .../generic/luaotfload/fontloader-font-shp.lua | 4 +- .../generic/luaotfload/fontloader-font-ttf.lua | 5 +- .../generic/luaotfload/fontloader-reference.lua | 415 +- .../generic/luaotfload/luaotfload-auxiliary.lua | 58 +- .../luatex/generic/luaotfload/luaotfload-case.lua | 239 + .../generic/luaotfload/luaotfload-colors.lua | 11 +- .../luatex/generic/luaotfload/luaotfload-conf.pdf | Bin 77426 -> 77331 bytes .../luaotfload/luaotfload-configuration.lua | 10 +- .../generic/luaotfload/luaotfload-database.lua | 31 +- .../generic/luaotfload/luaotfload-diagnostics.lua | 11 +- .../luatex/generic/luaotfload/luaotfload-dvi.lua | 10 +- .../generic/luaotfload/luaotfload-embolden.lua | 10 +- .../generic/luaotfload/luaotfload-fallback.lua | 10 +- .../generic/luaotfload/luaotfload-features.lua | 27 +- .../generic/luaotfload/luaotfload-filelist.lua | 14 +- .../generic/luaotfload/luaotfload-glyphlist.lua | 10 +- .../generic/luaotfload/luaotfload-harf-define.lua | 10 +- .../generic/luaotfload/luaotfload-harf-plug.lua | 563 +- .../luatex/generic/luaotfload/luaotfload-init.lua | 50 +- .../luatex/generic/luaotfload/luaotfload-latex.pdf | Bin 486239 -> 493305 bytes .../luatex/generic/luaotfload/luaotfload-latex.tex | 2 +- .../generic/luaotfload/luaotfload-letterspace.lua | 10 +- .../generic/luaotfload/luaotfload-loaders.lua | 10 +- .../luatex/generic/luaotfload/luaotfload-log.lua | 11 +- .../luatex/generic/luaotfload/luaotfload-main.lua | 339 +- .../luatex/generic/luaotfload/luaotfload-main.tex | 101 +- .../generic/luaotfload/luaotfload-multiscript.lua | 10 +- .../generic/luaotfload/luaotfload-notdef.lua | 10 +- .../generic/luaotfload/luaotfload-parsers.lua | 11 +- .../generic/luaotfload/luaotfload-resolvers.lua | 11 +- .../generic/luaotfload/luaotfload-scripts.lua | 10 +- .../generic/luaotfload/luaotfload-status.lua | 184 +- .../generic/luaotfload/luaotfload-suppress.lua | 10 +- .../luatex/generic/luaotfload/luaotfload-szss.lua | 10 +- macros/luatex/generic/luaotfload/luaotfload-tool.1 | 4 +- .../luatex/generic/luaotfload/luaotfload-tool.lua | 10 +- .../luatex/generic/luaotfload/luaotfload-tool.pdf | Bin 76886 -> 76773 bytes .../luatex/generic/luaotfload/luaotfload-tool.rst | 4 +- .../generic/luaotfload/luaotfload-tounicode.lua | 10 +- .../generic/luaotfload/luaotfload-unicode.lua | 152 +- macros/luatex/generic/luaotfload/luaotfload.conf.5 | 2 +- .../luatex/generic/luaotfload/luaotfload.conf.rst | 4 +- macros/luatex/generic/luaotfload/luaotfload.lua | 375 + macros/luatex/generic/luaotfload/luaotfload.sty | 4 +- macros/luatex/generic/luaotfload/scripts-demo.pdf | Bin 21504 -> 21696 bytes .../generic/luaotfload/shaper-demo-graphite.pdf | Bin 8468 -> 8566 bytes macros/luatex/generic/luaotfload/shaper-demo.pdf | Bin 8392 -> 8486 bytes systems/doc/metapost/mpman.pdf | Bin 957617 -> 959393 bytes .../source-manual/mpman-app-numbersystems.tex | 12 +- .../metapost/source-manual/mpman-app-refman.tex | 2 +- systems/doc/metapost/source-manual/mpman.tex | 10 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb | 570 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 | 2 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 | 2 +- .../texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc | 14 +- systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz | Bin 2257520 -> 2257956 bytes systems/win32/miktex/tm/packages/next/pr.ini | 8 +- systems/win32/miktex/tm/packages/pr.ini | 8 +- systems/win32/w32tex/ChangeLog | 9 + timestamp | 2 +- 217 files changed, 42508 insertions(+), 38943 deletions(-) delete mode 100644 macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.tex delete mode 100644 macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.tex delete mode 100644 macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.tex delete mode 100644 macros/latex/contrib/biblatex/latex/blx-case-expl3.def create mode 100644 macros/latex/contrib/biblatex/latex/blx-case-expl3.sty delete mode 100644 macros/latex/contrib/biblatex/latex/blx-case-latex2e.def create mode 100644 macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty create mode 100644 macros/latex/contrib/biblatex/latex/lbx/basque.lbx delete mode 100644 macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua create mode 100644 macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua create mode 100644 macros/luatex/generic/luaotfload/luaotfload-case.lua create mode 100644 macros/luatex/generic/luaotfload/luaotfload.lua diff --git a/FILES.byname b/FILES.byname index b9b92a52d8..5c0b5872ee 100644 --- a/FILES.byname +++ b/FILES.byname @@ -1,21 +1,20 @@ -2020/08/16 | 17861157 | biblio/biber/binaries/Cygwin/biber-cygwin32.tar.gz -2020/08/16 | 17970721 | biblio/biber/binaries/Cygwin/biber-cygwin64.tar.gz -2020/08/23 | 17851212 | biblio/biber/binaries/FreeBSD/biber-amd64-freebsd.tar.xz -2020/08/23 | 15939228 | biblio/biber/binaries/FreeBSD/biber-i386-freebsd.tar.xz -2020/08/17 | 16410243 | biblio/biber/binaries/Linux/biber-linux_x86_32.tar.gz -2020/08/16 | 19281953 | biblio/biber/binaries/Linux/biber-linux_x86_64.tar.gz -2020/08/16 | 19330984 | biblio/biber/binaries/Linux-musl/biber-linux_x86_64-musl.tar.gz -2020/08/16 | 29100616 | biblio/biber/binaries/OSX_Intel/biber-darwinlegacy_x86_64.tar.gz -2020/08/16 | 29250710 | biblio/biber/binaries/OSX_Intel/biber-darwin_x86_64.tar.gz -2020/08/16 | 15851968 | biblio/biber/binaries/Solaris_Intel/biber-i386-pc-solaris2.11.tar.xz -2020/08/16 | 16769268 | biblio/biber/binaries/Solaris_Intel/biber-x86_64-pc-solaris2.11.tar.xz -2020/08/16 | 23565603 | biblio/biber/binaries/Windows/biber-MSWIN32.zip -2020/08/16 | 23504906 | biblio/biber/binaries/Windows/biber-MSWIN64.zip -2020/08/16 | 265333 | biblio/biber/documentation/biber.pdf -2020/08/19 | 25506 | biblio/biber/documentation/Changes -2020/08/16 | 117927 | biblio/biber/documentation/utf8-macro-map.html +2020/12/27 | 18007106 | biblio/biber/binaries/Cygwin/biber-cygwin32.tar.gz +2020/12/27 | 18132544 | biblio/biber/binaries/Cygwin/biber-cygwin64.tar.gz +2020/12/28 | 22779316 | biblio/biber/binaries/FreeBSD/biber-amd64-freebsd.tar.xz +2020/12/28 | 20866528 | biblio/biber/binaries/FreeBSD/biber-i386-freebsd.tar.xz +2020/12/19 | 21671519 | biblio/biber/binaries/Linux/biber-linux_x86_32.tar.gz +2020/12/19 | 24634450 | biblio/biber/binaries/Linux/biber-linux_x86_64.tar.gz +2020/12/19 | 19629342 | biblio/biber/binaries/Linux-musl/biber-linux_x86_64-musl.tar.gz +2020/12/19 | 36087851 | biblio/biber/binaries/OSX_Intel/biber-darwinlegacy_x86_64.tar.gz +2020/12/19 | 34980609 | biblio/biber/binaries/OSX_Intel/biber-darwin_x86_64.tar.gz +2020/12/30 | 21925004 | biblio/biber/binaries/Solaris_Intel/biber-x86_64-pc-solaris2.11.tar.xz +2020/12/19 | 23889959 | biblio/biber/binaries/Windows/biber-MSWIN32.zip +2020/12/19 | 25621171 | biblio/biber/binaries/Windows/biber-MSWIN64.zip +2020/12/19 | 267307 | biblio/biber/documentation/biber.pdf +2020/12/31 | 25869 | biblio/biber/documentation/Changes +2020/12/19 | 117927 | biblio/biber/documentation/utf8-macro-map.html 2018/02/27 | 1856 | biblio/biber/README.md -2020/08/16 | 1032985 | biblio/biber/source/biblatex-biber.tar.gz +2020/12/19 | 1036248 | biblio/biber/source/biblatex-biber.tar.gz 2016/10/20 | 2078642 | biblio/bibfilex/Linux/GTK/bibfilex-gtk-1.2.8.0-1.i386.rpm 2016/10/20 | 2255722 | biblio/bibfilex/Linux/GTK/bibfilex-gtk-1.2.8.0-1.x86_64.rpm 2016/10/20 | 2072778 | biblio/bibfilex/Linux/GTK/bibfilex-gtk_1.2.8.0_amd64.deb @@ -5088,7 +5087,7 @@ 1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp 1990/10/02 | 812 | dviware/vutex/vaxvms.ins 1990/10/02 | 127576 | dviware/vutex/vutex.web -2020/12/30 | 173855 | FILES.last07days +2020/12/31 | 181356 | FILES.last07days 2020/08/14 | 104065 | fonts/academicons/academicons.pdf 2020/08/14 | 17247 | fonts/academicons/academicons.sty 2020/08/14 | 6546 | fonts/academicons/academicons.tex @@ -170098,7 +170097,7 @@ 2020/10/28 | 2643533 | install/macros/latex-dev/required/latex-amsmath-dev.tds.zip 2020/10/28 | 2533746 | install/macros/latex-dev/required/latex-graphics-dev.tds.zip 2020/10/28 | 6965729 | install/macros/latex-dev/required/latex-tools-dev.tds.zip -2020/10/26 | 28341919 | install/macros/latex/latex-base.tds.zip +2020/12/31 | 28396601 | install/macros/latex/latex-base.tds.zip 2020/06/01 | 1578753 | install/macros/latex/required/amscls.tds.zip 2020/12/16 | 2763879 | install/macros/latex/required/babel-base.tds.zip 2020/10/01 | 2643064 | install/macros/latex/required/latex-amsmath.tds.zip @@ -170109,9 +170108,9 @@ 2020/10/01 | 6964612 | install/macros/latex/required/latex-tools.tds.zip 2016/09/02 | 108688 | install/macros/luatex/generic/cstypo.tds.zip 2015/10/01 | 154538 | install/macros/luatex/generic/ctablestack.tds.zip -2020/09/02 | 273447 | install/macros/luatex/generic/lualibs.tds.zip +2020/12/31 | 273393 | install/macros/luatex/generic/lualibs.tds.zip 2020/12/30 | 196220 | install/macros/luatex/generic/luamplib.tds.zip -2020/09/02 | 1915770 | install/macros/luatex/generic/luaotfload.tds.zip +2020/12/31 | 1936733 | install/macros/luatex/generic/luaotfload.tds.zip 2015/10/04 | 277014 | install/macros/luatex/generic/luatexbase.tds.zip 2020/03/23 | 891718 | install/macros/luatex/latex/arabluatex.tds.zip 2020/11/04 | 721353 | install/macros/luatex/latex/ekdosis.tds.zip @@ -182980,7 +182979,7 @@ 2013/04/01 | 14776 | macros/context/contrib/context-visualcounter/tex/context/third/visualcounter/t-visualcounter.mkvi 2018/03/05 | 11 | macros/context/contrib/context-visualcounter/VERSION 2018/03/22 | 276789 | macros/context/contrib/context-visualcounter.zip -2020/12/28 | 119601928 | macros/context/latest/cont-tmf.zip +2020/12/30 | 119604689 | macros/context/latest/cont-tmf.zip 2016/04/21 | 32846 | macros/cstex/base/cmexb.tar.gz 2016/06/26 | 1728262 | macros/cstex/base/csfonts-t1.tar.gz 2007/03/01 | 187106 | macros/cstex/base/csfonts.tar.gz @@ -185912,260 +185911,260 @@ 1993/11/08 | 1691 | macros/latex209/contrib/zero/zero-test.tex 2006/09/21 | 3505 | macros/latex209/contrib/zero.zip 1997/01/22 | 274 | macros/latex209/distribs/README.obsolete -2020/10/26 | 6654 | macros/latex/base/alltt.dtx -2020/10/26 | 2892 | macros/latex/base/alltt.ins -2020/10/26 | 173079 | macros/latex/base/alltt.pdf -2020/10/26 | 3294 | macros/latex/base/bugs.txt -2020/10/26 | 220217 | macros/latex/base/cfgguide.pdf -2020/10/26 | 22457 | macros/latex/base/cfgguide.tex -2020/10/26 | 42708 | macros/latex/base/changes.old.txt -2020/10/26 | 359540 | macros/latex/base/changes.txt -2020/10/26 | 155735 | macros/latex/base/classes.dtx -2020/10/26 | 4089 | macros/latex/base/classes.ins -2020/10/26 | 520851 | macros/latex/base/classes.pdf -2020/10/26 | 372555 | macros/latex/base/clsguide.pdf -2020/10/26 | 69051 | macros/latex/base/clsguide.tex -2020/10/26 | 5275 | macros/latex/base/cmextra.ins -2020/10/26 | 43637 | macros/latex/base/cmfonts.fdd -2020/10/26 | 4326 | macros/latex/base/cmfonts.ins -2020/10/26 | 264505 | macros/latex/base/cmfonts.pdf -2020/10/26 | 216997 | macros/latex/base/cyrguide.pdf -2020/10/26 | 17496 | macros/latex/base/cyrguide.tex -2020/10/26 | 204016 | macros/latex/base/doc.dtx -2020/10/26 | 630922 | macros/latex/base/doc.pdf -2020/10/26 | 170214 | macros/latex/base/docstrip.dtx -2020/10/26 | 4223 | macros/latex/base/docstrip.ins -2020/10/26 | 479544 | macros/latex/base/docstrip.pdf -2020/10/26 | 4392 | macros/latex/base/ec.ins -2020/10/26 | 1532144 | macros/latex/base/encguide.pdf -2020/10/26 | 52814 | macros/latex/base/encguide.tex -2020/10/26 | 7222 | macros/latex/base/exscale.dtx -2020/10/26 | 3340 | macros/latex/base/exscale.ins -2020/10/26 | 195877 | macros/latex/base/exscale.pdf -2020/10/26 | 23521 | macros/latex/base/fix-cm.dtx -2020/10/26 | 2894 | macros/latex/base/fix-cm.ins -2020/10/26 | 262059 | macros/latex/base/fix-cm.pdf -2020/10/26 | 417861 | macros/latex/base/fntguide.pdf -2020/10/26 | 90413 | macros/latex/base/fntguide.tex -2020/10/26 | 60334 | macros/latex/base/fontdef.dtx -2020/10/26 | 9460 | macros/latex/base/format.ins -2020/10/26 | 5515 | macros/latex/base/graphpap.dtx -2020/10/26 | 2894 | macros/latex/base/graphpap.ins -2020/10/26 | 156277 | macros/latex/base/graphpap.pdf -2020/10/26 | 2706 | macros/latex/base/idx.tex -2020/10/26 | 18305 | macros/latex/base/ifthen.dtx -2020/10/26 | 2890 | macros/latex/base/ifthen.ins -2020/10/26 | 205213 | macros/latex/base/ifthen.pdf -2020/10/26 | 106914 | macros/latex/base/inputenc.dtx -2020/10/26 | 5716 | macros/latex/base/inputenc.ins -2020/10/26 | 294900 | macros/latex/base/inputenc.pdf -2020/10/26 | 4080 | macros/latex/base/lablst.tex -2020/10/26 | 38735 | macros/latex/base/latex209.dtx -2020/10/26 | 4221 | macros/latex/base/latex209.ins -2020/10/26 | 232390 | macros/latex/base/latexchanges.pdf -2020/10/26 | 37980 | macros/latex/base/latexchanges.tex -2020/10/26 | 32164 | macros/latex/base/latexrelease.dtx -2020/10/26 | 5600 | macros/latex/base/latexrelease.ins -2020/10/26 | 246195 | macros/latex/base/latexrelease.pdf -2020/10/26 | 6715 | macros/latex/base/latexsym.dtx -2020/10/26 | 5044 | macros/latex/base/latexsym.ins -2020/10/26 | 192297 | macros/latex/base/latexsym.pdf -2020/10/26 | 52532 | macros/latex/base/lb2.err -2020/10/26 | 138219 | macros/latex/base/lb2.pdf -2020/10/26 | 1381 | macros/latex/base/legal.txt -2020/10/26 | 62436 | macros/latex/base/letter.dtx -2020/10/26 | 3374 | macros/latex/base/letter.ins -2020/10/26 | 305700 | macros/latex/base/letter.pdf -2020/10/26 | 20434 | macros/latex/base/lgc2.err -2020/10/26 | 101343 | macros/latex/base/lgc2.pdf -2020/10/26 | 9068 | macros/latex/base/lppl-1-0.txt -2020/10/26 | 14341 | macros/latex/base/lppl-1-1.txt -2020/10/26 | 14421 | macros/latex/base/lppl-1-2.txt -2020/10/26 | 125830 | macros/latex/base/lppl.pdf -2020/10/26 | 23386 | macros/latex/base/lppl.tex -2020/10/26 | 19040 | macros/latex/base/lppl.txt -2020/10/26 | 4304 | macros/latex/base/ltalloc.dtx -2020/10/26 | 14440 | macros/latex/base/ltbibl.dtx -2020/10/26 | 41587 | macros/latex/base/ltboxes.dtx -2020/10/26 | 122389 | macros/latex/base/ltclass.dtx -2020/10/26 | 9562 | macros/latex/base/ltcntrl.dtx -2020/10/26 | 22676 | macros/latex/base/ltcounts.dtx -2020/10/26 | 85316 | macros/latex/base/ltdefns.dtx -2020/10/26 | 35221 | macros/latex/base/ltdirchk.dtx -2020/10/26 | 24016 | macros/latex/base/lterror.dtx -2020/10/26 | 10045 | macros/latex/base/ltexpl.dtx -2020/10/26 | 735464 | macros/latex/base/ltfilehook-code.pdf -2020/10/26 | 105 | macros/latex/base/ltfilehook-code.tex -2020/10/26 | 516397 | macros/latex/base/ltfilehook-doc.pdf -2020/10/26 | 180 | macros/latex/base/ltfilehook-doc.tex -2020/10/26 | 54391 | macros/latex/base/ltfilehook.dtx -2020/10/26 | 52648 | macros/latex/base/ltfiles.dtx -2020/10/26 | 40877 | macros/latex/base/ltfinal.dtx -2020/10/26 | 51314 | macros/latex/base/ltfloat.dtx -2020/10/26 | 29194 | macros/latex/base/ltfntcmd.dtx -2020/10/26 | 49967 | macros/latex/base/ltfssaxes.dtx -2020/10/26 | 79110 | macros/latex/base/ltfssbas.dtx -2020/10/26 | 10376 | macros/latex/base/ltfsscmp.dtx -2020/10/26 | 61221 | macros/latex/base/ltfssdcl.dtx -2020/10/26 | 74092 | macros/latex/base/ltfssini.dtx -2020/10/26 | 67333 | macros/latex/base/ltfsstrc.dtx -2020/10/26 | 901929 | macros/latex/base/lthooks-code.pdf -2020/10/26 | 102 | macros/latex/base/lthooks-code.tex -2020/10/26 | 621088 | macros/latex/base/lthooks-doc.pdf -2020/10/26 | 177 | macros/latex/base/lthooks-doc.tex -2020/10/26 | 150801 | macros/latex/base/lthooks.dtx -2020/10/26 | 4952 | macros/latex/base/lthyphen.dtx -2020/10/26 | 5865 | macros/latex/base/ltidxglo.dtx -2020/10/26 | 4762 | macros/latex/base/ltlength.dtx -2020/10/26 | 36154 | macros/latex/base/ltlists.dtx -2020/10/26 | 3731 | macros/latex/base/ltlogos.dtx -2020/10/26 | 64482 | macros/latex/base/ltluatex.dtx -2020/10/26 | 305339 | macros/latex/base/ltluatex.pdf -2020/10/26 | 38948 | macros/latex/base/ltmath.dtx -2020/10/26 | 57665 | macros/latex/base/ltmiscen.dtx -2020/10/26 | 150020 | macros/latex/base/ltnews01.pdf -2020/10/26 | 5239 | macros/latex/base/ltnews01.tex -2020/10/26 | 134751 | macros/latex/base/ltnews02.pdf -2020/10/26 | 5284 | macros/latex/base/ltnews02.tex -2020/10/26 | 134742 | macros/latex/base/ltnews03.pdf -2020/10/26 | 5201 | macros/latex/base/ltnews03.tex -2020/10/26 | 128772 | macros/latex/base/ltnews04.pdf -2020/10/26 | 5507 | macros/latex/base/ltnews04.tex -2020/10/26 | 157181 | macros/latex/base/ltnews05.pdf -2020/10/26 | 5609 | macros/latex/base/ltnews05.tex -2020/10/26 | 133138 | macros/latex/base/ltnews06.pdf -2020/10/26 | 5391 | macros/latex/base/ltnews06.tex -2020/10/26 | 124029 | macros/latex/base/ltnews07.pdf -2020/10/26 | 5426 | macros/latex/base/ltnews07.tex -2020/10/26 | 144482 | macros/latex/base/ltnews08.pdf -2020/10/26 | 5696 | macros/latex/base/ltnews08.tex -2020/10/26 | 120222 | macros/latex/base/ltnews09.pdf -2020/10/26 | 5294 | macros/latex/base/ltnews09.tex -2020/10/26 | 147946 | macros/latex/base/ltnews10.pdf -2020/10/26 | 5660 | macros/latex/base/ltnews10.tex -2020/10/26 | 104936 | macros/latex/base/ltnews11.pdf -2020/10/26 | 5530 | macros/latex/base/ltnews11.tex -2020/10/26 | 137919 | macros/latex/base/ltnews12.pdf -2020/10/26 | 5418 | macros/latex/base/ltnews12.tex -2020/10/26 | 161065 | macros/latex/base/ltnews13.pdf -2020/10/26 | 6872 | macros/latex/base/ltnews13.tex -2020/10/26 | 150907 | macros/latex/base/ltnews14.pdf -2020/10/26 | 6274 | macros/latex/base/ltnews14.tex -2020/10/26 | 122092 | macros/latex/base/ltnews15.pdf -2020/10/26 | 5840 | macros/latex/base/ltnews15.tex -2020/10/26 | 130687 | macros/latex/base/ltnews16.pdf -2020/10/26 | 5777 | macros/latex/base/ltnews16.tex -2020/10/26 | 149838 | macros/latex/base/ltnews17.pdf -2020/10/26 | 8864 | macros/latex/base/ltnews17.tex -2020/10/26 | 36005 | macros/latex/base/ltnews18.pdf -2020/10/26 | 1342 | macros/latex/base/ltnews18.tex -2020/10/26 | 235073 | macros/latex/base/ltnews19.pdf -2020/10/26 | 4171 | macros/latex/base/ltnews19.tex -2020/10/26 | 283318 | macros/latex/base/ltnews20.pdf -2020/10/26 | 7326 | macros/latex/base/ltnews20.tex -2020/10/26 | 233492 | macros/latex/base/ltnews21.pdf -2020/10/26 | 9810 | macros/latex/base/ltnews21.tex -2020/10/26 | 302836 | macros/latex/base/ltnews22.pdf -2020/10/26 | 10669 | macros/latex/base/ltnews22.tex -2020/10/26 | 274459 | macros/latex/base/ltnews23.pdf -2020/10/26 | 10688 | macros/latex/base/ltnews23.tex -2020/10/26 | 252645 | macros/latex/base/ltnews24.pdf -2020/10/26 | 12225 | macros/latex/base/ltnews24.tex -2020/10/26 | 196326 | macros/latex/base/ltnews25.pdf -2020/10/26 | 5474 | macros/latex/base/ltnews25.tex -2020/10/26 | 362839 | macros/latex/base/ltnews26.pdf -2020/10/26 | 10698 | macros/latex/base/ltnews26.tex -2020/10/26 | 239758 | macros/latex/base/ltnews27.pdf -2020/10/26 | 5507 | macros/latex/base/ltnews27.tex -2020/10/26 | 368226 | macros/latex/base/ltnews28.pdf -2020/10/26 | 14892 | macros/latex/base/ltnews28.tex -2020/10/26 | 433004 | macros/latex/base/ltnews29.pdf -2020/10/26 | 18941 | macros/latex/base/ltnews29.tex -2020/10/26 | 491246 | macros/latex/base/ltnews30.pdf -2020/10/26 | 23652 | macros/latex/base/ltnews30.tex -2020/10/26 | 500919 | macros/latex/base/ltnews31.pdf -2020/10/26 | 30457 | macros/latex/base/ltnews31.tex -2020/10/26 | 520923 | macros/latex/base/ltnews32.pdf -2020/10/26 | 33256 | macros/latex/base/ltnews32.tex -2020/10/26 | 20471 | macros/latex/base/ltnews.cls -2020/10/26 | 989398 | macros/latex/base/ltnews.pdf -2020/10/26 | 8100 | macros/latex/base/ltnews.tex -2020/10/26 | 145163 | macros/latex/base/ltoutenc.dtx -2020/10/26 | 3369 | macros/latex/base/ltoutenc.ins -2020/10/26 | 175629 | macros/latex/base/ltoutput.dtx -2020/10/26 | 11591 | macros/latex/base/ltpage.dtx -2020/10/26 | 2733 | macros/latex/base/ltpageno.dtx -2020/10/26 | 5854 | macros/latex/base/ltpar.dtx -2020/10/26 | 68914 | macros/latex/base/ltpictur.dtx -2020/10/26 | 48645 | macros/latex/base/ltplain.dtx -2020/10/26 | 32647 | macros/latex/base/ltsect.dtx -2020/10/26 | 749471 | macros/latex/base/ltshipout-code.pdf -2020/10/26 | 104 | macros/latex/base/ltshipout-code.tex -2020/10/26 | 503979 | macros/latex/base/ltshipout-doc.pdf -2020/10/26 | 179 | macros/latex/base/ltshipout-doc.tex -2020/10/26 | 60816 | macros/latex/base/ltshipout.dtx -2020/10/26 | 45246 | macros/latex/base/ltspace.dtx -2020/10/26 | 47704 | macros/latex/base/lttab.dtx -2020/10/26 | 88411 | macros/latex/base/lttextcomp.dtx -2020/10/26 | 8737 | macros/latex/base/ltthm.dtx -2020/10/26 | 10327 | macros/latex/base/ltvers.dtx -2020/10/26 | 191527 | macros/latex/base/ltx3info.pdf -2020/10/26 | 18300 | macros/latex/base/ltx3info.tex -2020/10/26 | 27124 | macros/latex/base/ltxcheck.tex -2020/10/26 | 19064 | macros/latex/base/ltxdoc.dtx -2020/10/26 | 215102 | macros/latex/base/ltxdoc.pdf -2020/10/26 | 7526 | macros/latex/base/ltxguide.cls -2020/10/26 | 15623 | macros/latex/base/ltxref.dtx -2020/10/26 | 10606 | macros/latex/base/makeindx.dtx -2020/10/26 | 3436 | macros/latex/base/makeindx.ins -2020/10/26 | 160667 | macros/latex/base/makeindx.pdf -2020/10/26 | 10690 | macros/latex/base/manifest.txt -2020/10/26 | 12946 | macros/latex/base/manual.err -2020/10/26 | 151347 | macros/latex/base/manual.pdf -2020/10/26 | 1938 | macros/latex/base/minimal.cls -2020/10/26 | 220388 | macros/latex/base/modguide.pdf -2020/10/26 | 16234 | macros/latex/base/modguide.tex -2020/10/26 | 4256 | macros/latex/base/newdc.ins -2020/10/26 | 6363 | macros/latex/base/newlfont.dtx -2020/10/26 | 18407 | macros/latex/base/nfssfont.dtx -2020/10/26 | 2895 | macros/latex/base/nfssfont.ins -2020/10/26 | 202451 | macros/latex/base/nfssfont.pdf -2020/10/26 | 3962 | macros/latex/base/olddc.ins -2020/10/26 | 8632 | macros/latex/base/oldlfont.dtx -2020/10/26 | 9374 | macros/latex/base/preload.dtx -2020/10/26 | 13305 | macros/latex/base/proc.dtx -2020/10/26 | 3403 | macros/latex/base/proc.ins -2020/10/26 | 216877 | macros/latex/base/proc.pdf -2020/10/26 | 3514 | macros/latex/base/README.md -2020/10/26 | 7200 | macros/latex/base/sample2e.tex -2020/10/26 | 89720 | macros/latex/base/slides.dtx -2020/10/26 | 6764 | macros/latex/base/slides.ins -2020/10/26 | 351586 | macros/latex/base/slides.pdf -2020/10/26 | 15701 | macros/latex/base/slifonts.fdd -2020/10/26 | 214710 | macros/latex/base/slifonts.pdf -2020/10/26 | 1694 | macros/latex/base/small2e.tex -2020/10/26 | 6367 | macros/latex/base/source2edoc.cls -2020/10/26 | 4349921 | macros/latex/base/source2e.pdf -2020/10/26 | 14918 | macros/latex/base/source2e.tex -2020/10/26 | 9401 | macros/latex/base/syntonly.dtx -2020/10/26 | 2898 | macros/latex/base/syntonly.ins -2020/10/26 | 181390 | macros/latex/base/syntonly.pdf -2020/10/26 | 12521 | macros/latex/base/testpage.tex -2020/10/26 | 2738 | macros/latex/base/tex2.txt -2020/10/26 | 8493 | macros/latex/base/texpert.txt -2020/10/26 | 172216 | macros/latex/base/tlc2.err -2020/10/26 | 164947 | macros/latex/base/tlc2.pdf -2020/10/26 | 12120 | macros/latex/base/tulm.fdd -2020/10/26 | 3783 | macros/latex/base/tulm.ins -2020/10/26 | 156546 | macros/latex/base/tulm.pdf -2020/10/26 | 3182 | macros/latex/base/unpack.ins -2020/10/26 | 399035 | macros/latex/base/usrguide.pdf -2020/10/26 | 68428 | macros/latex/base/usrguide.tex -2020/10/26 | 89386 | macros/latex/base/utf8ienc.dtx -2020/10/26 | 330853 | macros/latex/base/utf8ienc.pdf -2020/10/26 | 10053 | macros/latex/base/webcomp.err -2020/10/26 | 136159 | macros/latex/base/webcomp.pdf -2020/10/26 | 27891050 | macros/latex/base.zip +2020/12/31 | 6654 | macros/latex/base/alltt.dtx +2020/12/31 | 2892 | macros/latex/base/alltt.ins +2020/12/31 | 173079 | macros/latex/base/alltt.pdf +2020/12/31 | 3294 | macros/latex/base/bugs.txt +2020/12/31 | 220217 | macros/latex/base/cfgguide.pdf +2020/12/31 | 22457 | macros/latex/base/cfgguide.tex +2020/12/31 | 42708 | macros/latex/base/changes.old.txt +2020/12/31 | 362219 | macros/latex/base/changes.txt +2020/12/31 | 155735 | macros/latex/base/classes.dtx +2020/12/31 | 4089 | macros/latex/base/classes.ins +2020/12/31 | 520851 | macros/latex/base/classes.pdf +2020/12/31 | 372555 | macros/latex/base/clsguide.pdf +2020/12/31 | 69051 | macros/latex/base/clsguide.tex +2020/12/31 | 5275 | macros/latex/base/cmextra.ins +2020/12/31 | 43637 | macros/latex/base/cmfonts.fdd +2020/12/31 | 4326 | macros/latex/base/cmfonts.ins +2020/12/31 | 264505 | macros/latex/base/cmfonts.pdf +2020/12/31 | 216997 | macros/latex/base/cyrguide.pdf +2020/12/31 | 17496 | macros/latex/base/cyrguide.tex +2020/12/31 | 204016 | macros/latex/base/doc.dtx +2020/12/31 | 631201 | macros/latex/base/doc.pdf +2020/12/31 | 170214 | macros/latex/base/docstrip.dtx +2020/12/31 | 4223 | macros/latex/base/docstrip.ins +2020/12/31 | 479501 | macros/latex/base/docstrip.pdf +2020/12/31 | 4392 | macros/latex/base/ec.ins +2020/12/31 | 1532144 | macros/latex/base/encguide.pdf +2020/12/31 | 52814 | macros/latex/base/encguide.tex +2020/12/31 | 7222 | macros/latex/base/exscale.dtx +2020/12/31 | 3340 | macros/latex/base/exscale.ins +2020/12/31 | 195877 | macros/latex/base/exscale.pdf +2020/12/31 | 23521 | macros/latex/base/fix-cm.dtx +2020/12/31 | 2894 | macros/latex/base/fix-cm.ins +2020/12/31 | 262059 | macros/latex/base/fix-cm.pdf +2020/12/31 | 418342 | macros/latex/base/fntguide.pdf +2020/12/31 | 90768 | macros/latex/base/fntguide.tex +2020/12/31 | 60334 | macros/latex/base/fontdef.dtx +2020/12/31 | 9460 | macros/latex/base/format.ins +2020/12/31 | 5515 | macros/latex/base/graphpap.dtx +2020/12/31 | 2894 | macros/latex/base/graphpap.ins +2020/12/31 | 156277 | macros/latex/base/graphpap.pdf +2020/12/31 | 2706 | macros/latex/base/idx.tex +2020/12/31 | 18305 | macros/latex/base/ifthen.dtx +2020/12/31 | 2890 | macros/latex/base/ifthen.ins +2020/12/31 | 205213 | macros/latex/base/ifthen.pdf +2020/12/31 | 106914 | macros/latex/base/inputenc.dtx +2020/12/31 | 5716 | macros/latex/base/inputenc.ins +2020/12/31 | 294900 | macros/latex/base/inputenc.pdf +2020/12/31 | 4080 | macros/latex/base/lablst.tex +2020/12/31 | 38735 | macros/latex/base/latex209.dtx +2020/12/31 | 4221 | macros/latex/base/latex209.ins +2020/12/31 | 232390 | macros/latex/base/latexchanges.pdf +2020/12/31 | 37980 | macros/latex/base/latexchanges.tex +2020/12/31 | 32164 | macros/latex/base/latexrelease.dtx +2020/12/31 | 5725 | macros/latex/base/latexrelease.ins +2020/12/31 | 246195 | macros/latex/base/latexrelease.pdf +2020/12/31 | 6715 | macros/latex/base/latexsym.dtx +2020/12/31 | 5044 | macros/latex/base/latexsym.ins +2020/12/31 | 192297 | macros/latex/base/latexsym.pdf +2020/12/31 | 52532 | macros/latex/base/lb2.err +2020/12/31 | 138219 | macros/latex/base/lb2.pdf +2020/12/31 | 1381 | macros/latex/base/legal.txt +2020/12/31 | 62436 | macros/latex/base/letter.dtx +2020/12/31 | 3374 | macros/latex/base/letter.ins +2020/12/31 | 305786 | macros/latex/base/letter.pdf +2020/12/31 | 20434 | macros/latex/base/lgc2.err +2020/12/31 | 101343 | macros/latex/base/lgc2.pdf +2020/12/31 | 9068 | macros/latex/base/lppl-1-0.txt +2020/12/31 | 14341 | macros/latex/base/lppl-1-1.txt +2020/12/31 | 14421 | macros/latex/base/lppl-1-2.txt +2020/12/31 | 125830 | macros/latex/base/lppl.pdf +2020/12/31 | 23386 | macros/latex/base/lppl.tex +2020/12/31 | 19040 | macros/latex/base/lppl.txt +2020/12/31 | 4304 | macros/latex/base/ltalloc.dtx +2020/12/31 | 14440 | macros/latex/base/ltbibl.dtx +2020/12/31 | 41587 | macros/latex/base/ltboxes.dtx +2020/12/31 | 128863 | macros/latex/base/ltclass.dtx +2020/12/31 | 9562 | macros/latex/base/ltcntrl.dtx +2020/12/31 | 22676 | macros/latex/base/ltcounts.dtx +2020/12/31 | 85744 | macros/latex/base/ltdefns.dtx +2020/12/31 | 35221 | macros/latex/base/ltdirchk.dtx +2020/12/31 | 24016 | macros/latex/base/lterror.dtx +2020/12/31 | 13703 | macros/latex/base/ltexpl.dtx +2020/12/31 | 744388 | macros/latex/base/ltfilehook-code.pdf +2020/12/31 | 105 | macros/latex/base/ltfilehook-code.tex +2020/12/31 | 516587 | macros/latex/base/ltfilehook-doc.pdf +2020/12/31 | 180 | macros/latex/base/ltfilehook-doc.tex +2020/12/31 | 59498 | macros/latex/base/ltfilehook.dtx +2020/12/31 | 52648 | macros/latex/base/ltfiles.dtx +2020/12/31 | 40877 | macros/latex/base/ltfinal.dtx +2020/12/31 | 51314 | macros/latex/base/ltfloat.dtx +2020/12/31 | 29194 | macros/latex/base/ltfntcmd.dtx +2020/12/31 | 49972 | macros/latex/base/ltfssaxes.dtx +2020/12/31 | 79873 | macros/latex/base/ltfssbas.dtx +2020/12/31 | 10376 | macros/latex/base/ltfsscmp.dtx +2020/12/31 | 61221 | macros/latex/base/ltfssdcl.dtx +2020/12/31 | 74092 | macros/latex/base/ltfssini.dtx +2020/12/31 | 67333 | macros/latex/base/ltfsstrc.dtx +2020/12/31 | 926391 | macros/latex/base/lthooks-code.pdf +2020/12/31 | 102 | macros/latex/base/lthooks-code.tex +2020/12/31 | 626854 | macros/latex/base/lthooks-doc.pdf +2020/12/31 | 177 | macros/latex/base/lthooks-doc.tex +2020/12/31 | 165558 | macros/latex/base/lthooks.dtx +2020/12/31 | 4952 | macros/latex/base/lthyphen.dtx +2020/12/31 | 5865 | macros/latex/base/ltidxglo.dtx +2020/12/31 | 4762 | macros/latex/base/ltlength.dtx +2020/12/31 | 36154 | macros/latex/base/ltlists.dtx +2020/12/31 | 3731 | macros/latex/base/ltlogos.dtx +2020/12/31 | 64482 | macros/latex/base/ltluatex.dtx +2020/12/31 | 305339 | macros/latex/base/ltluatex.pdf +2020/12/31 | 39244 | macros/latex/base/ltmath.dtx +2020/12/31 | 57209 | macros/latex/base/ltmiscen.dtx +2020/12/31 | 150020 | macros/latex/base/ltnews01.pdf +2020/12/31 | 5239 | macros/latex/base/ltnews01.tex +2020/12/31 | 134751 | macros/latex/base/ltnews02.pdf +2020/12/31 | 5284 | macros/latex/base/ltnews02.tex +2020/12/31 | 134742 | macros/latex/base/ltnews03.pdf +2020/12/31 | 5201 | macros/latex/base/ltnews03.tex +2020/12/31 | 128772 | macros/latex/base/ltnews04.pdf +2020/12/31 | 5507 | macros/latex/base/ltnews04.tex +2020/12/31 | 157181 | macros/latex/base/ltnews05.pdf +2020/12/31 | 5609 | macros/latex/base/ltnews05.tex +2020/12/31 | 133138 | macros/latex/base/ltnews06.pdf +2020/12/31 | 5391 | macros/latex/base/ltnews06.tex +2020/12/31 | 124029 | macros/latex/base/ltnews07.pdf +2020/12/31 | 5426 | macros/latex/base/ltnews07.tex +2020/12/31 | 144482 | macros/latex/base/ltnews08.pdf +2020/12/31 | 5696 | macros/latex/base/ltnews08.tex +2020/12/31 | 120222 | macros/latex/base/ltnews09.pdf +2020/12/31 | 5294 | macros/latex/base/ltnews09.tex +2020/12/31 | 147946 | macros/latex/base/ltnews10.pdf +2020/12/31 | 5660 | macros/latex/base/ltnews10.tex +2020/12/31 | 104936 | macros/latex/base/ltnews11.pdf +2020/12/31 | 5530 | macros/latex/base/ltnews11.tex +2020/12/31 | 137919 | macros/latex/base/ltnews12.pdf +2020/12/31 | 5418 | macros/latex/base/ltnews12.tex +2020/12/31 | 161065 | macros/latex/base/ltnews13.pdf +2020/12/31 | 6872 | macros/latex/base/ltnews13.tex +2020/12/31 | 150907 | macros/latex/base/ltnews14.pdf +2020/12/31 | 6274 | macros/latex/base/ltnews14.tex +2020/12/31 | 122092 | macros/latex/base/ltnews15.pdf +2020/12/31 | 5840 | macros/latex/base/ltnews15.tex +2020/12/31 | 130687 | macros/latex/base/ltnews16.pdf +2020/12/31 | 5777 | macros/latex/base/ltnews16.tex +2020/12/31 | 149838 | macros/latex/base/ltnews17.pdf +2020/12/31 | 8864 | macros/latex/base/ltnews17.tex +2020/12/31 | 36005 | macros/latex/base/ltnews18.pdf +2020/12/31 | 1342 | macros/latex/base/ltnews18.tex +2020/12/31 | 235073 | macros/latex/base/ltnews19.pdf +2020/12/31 | 4171 | macros/latex/base/ltnews19.tex +2020/12/31 | 283318 | macros/latex/base/ltnews20.pdf +2020/12/31 | 7326 | macros/latex/base/ltnews20.tex +2020/12/31 | 233492 | macros/latex/base/ltnews21.pdf +2020/12/31 | 9810 | macros/latex/base/ltnews21.tex +2020/12/31 | 302836 | macros/latex/base/ltnews22.pdf +2020/12/31 | 10669 | macros/latex/base/ltnews22.tex +2020/12/31 | 274459 | macros/latex/base/ltnews23.pdf +2020/12/31 | 10688 | macros/latex/base/ltnews23.tex +2020/12/31 | 252645 | macros/latex/base/ltnews24.pdf +2020/12/31 | 12225 | macros/latex/base/ltnews24.tex +2020/12/31 | 196326 | macros/latex/base/ltnews25.pdf +2020/12/31 | 5474 | macros/latex/base/ltnews25.tex +2020/12/31 | 362839 | macros/latex/base/ltnews26.pdf +2020/12/31 | 10698 | macros/latex/base/ltnews26.tex +2020/12/31 | 239758 | macros/latex/base/ltnews27.pdf +2020/12/31 | 5507 | macros/latex/base/ltnews27.tex +2020/12/31 | 368226 | macros/latex/base/ltnews28.pdf +2020/12/31 | 14892 | macros/latex/base/ltnews28.tex +2020/12/31 | 433004 | macros/latex/base/ltnews29.pdf +2020/12/31 | 18941 | macros/latex/base/ltnews29.tex +2020/12/31 | 491246 | macros/latex/base/ltnews30.pdf +2020/12/31 | 23652 | macros/latex/base/ltnews30.tex +2020/12/31 | 500919 | macros/latex/base/ltnews31.pdf +2020/12/31 | 30457 | macros/latex/base/ltnews31.tex +2020/12/31 | 520923 | macros/latex/base/ltnews32.pdf +2020/12/31 | 33256 | macros/latex/base/ltnews32.tex +2020/12/31 | 20471 | macros/latex/base/ltnews.cls +2020/12/31 | 989398 | macros/latex/base/ltnews.pdf +2020/12/31 | 8100 | macros/latex/base/ltnews.tex +2020/12/31 | 145163 | macros/latex/base/ltoutenc.dtx +2020/12/31 | 3369 | macros/latex/base/ltoutenc.ins +2020/12/31 | 175629 | macros/latex/base/ltoutput.dtx +2020/12/31 | 11591 | macros/latex/base/ltpage.dtx +2020/12/31 | 2733 | macros/latex/base/ltpageno.dtx +2020/12/31 | 5854 | macros/latex/base/ltpar.dtx +2020/12/31 | 68914 | macros/latex/base/ltpictur.dtx +2020/12/31 | 48645 | macros/latex/base/ltplain.dtx +2020/12/31 | 32647 | macros/latex/base/ltsect.dtx +2020/12/31 | 750748 | macros/latex/base/ltshipout-code.pdf +2020/12/31 | 104 | macros/latex/base/ltshipout-code.tex +2020/12/31 | 503965 | macros/latex/base/ltshipout-doc.pdf +2020/12/31 | 179 | macros/latex/base/ltshipout-doc.tex +2020/12/31 | 61441 | macros/latex/base/ltshipout.dtx +2020/12/31 | 45246 | macros/latex/base/ltspace.dtx +2020/12/31 | 47704 | macros/latex/base/lttab.dtx +2020/12/31 | 88411 | macros/latex/base/lttextcomp.dtx +2020/12/31 | 8737 | macros/latex/base/ltthm.dtx +2020/12/31 | 10327 | macros/latex/base/ltvers.dtx +2020/12/31 | 191527 | macros/latex/base/ltx3info.pdf +2020/12/31 | 18300 | macros/latex/base/ltx3info.tex +2020/12/31 | 27124 | macros/latex/base/ltxcheck.tex +2020/12/31 | 19064 | macros/latex/base/ltxdoc.dtx +2020/12/31 | 215102 | macros/latex/base/ltxdoc.pdf +2020/12/31 | 7526 | macros/latex/base/ltxguide.cls +2020/12/31 | 15623 | macros/latex/base/ltxref.dtx +2020/12/31 | 10606 | macros/latex/base/makeindx.dtx +2020/12/31 | 3436 | macros/latex/base/makeindx.ins +2020/12/31 | 160667 | macros/latex/base/makeindx.pdf +2020/12/31 | 10690 | macros/latex/base/manifest.txt +2020/12/31 | 12946 | macros/latex/base/manual.err +2020/12/31 | 151347 | macros/latex/base/manual.pdf +2020/12/31 | 1938 | macros/latex/base/minimal.cls +2020/12/31 | 220388 | macros/latex/base/modguide.pdf +2020/12/31 | 16234 | macros/latex/base/modguide.tex +2020/12/31 | 4256 | macros/latex/base/newdc.ins +2020/12/31 | 6363 | macros/latex/base/newlfont.dtx +2020/12/31 | 18407 | macros/latex/base/nfssfont.dtx +2020/12/31 | 2895 | macros/latex/base/nfssfont.ins +2020/12/31 | 202451 | macros/latex/base/nfssfont.pdf +2020/12/31 | 3962 | macros/latex/base/olddc.ins +2020/12/31 | 8632 | macros/latex/base/oldlfont.dtx +2020/12/31 | 9374 | macros/latex/base/preload.dtx +2020/12/31 | 13305 | macros/latex/base/proc.dtx +2020/12/31 | 3403 | macros/latex/base/proc.ins +2020/12/31 | 216877 | macros/latex/base/proc.pdf +2020/12/31 | 3514 | macros/latex/base/README.md +2020/12/31 | 7200 | macros/latex/base/sample2e.tex +2020/12/31 | 89720 | macros/latex/base/slides.dtx +2020/12/31 | 6764 | macros/latex/base/slides.ins +2020/12/31 | 351586 | macros/latex/base/slides.pdf +2020/12/31 | 15701 | macros/latex/base/slifonts.fdd +2020/12/31 | 214710 | macros/latex/base/slifonts.pdf +2020/12/31 | 1694 | macros/latex/base/small2e.tex +2020/12/31 | 7627 | macros/latex/base/source2edoc.cls +2020/12/31 | 4357396 | macros/latex/base/source2e.pdf +2020/12/31 | 14918 | macros/latex/base/source2e.tex +2020/12/31 | 9401 | macros/latex/base/syntonly.dtx +2020/12/31 | 2898 | macros/latex/base/syntonly.ins +2020/12/31 | 181787 | macros/latex/base/syntonly.pdf +2020/12/31 | 12521 | macros/latex/base/testpage.tex +2020/12/31 | 2738 | macros/latex/base/tex2.txt +2020/12/31 | 8493 | macros/latex/base/texpert.txt +2020/12/31 | 172216 | macros/latex/base/tlc2.err +2020/12/31 | 164947 | macros/latex/base/tlc2.pdf +2020/12/31 | 12120 | macros/latex/base/tulm.fdd +2020/12/31 | 3783 | macros/latex/base/tulm.ins +2020/12/31 | 156546 | macros/latex/base/tulm.pdf +2020/12/31 | 3182 | macros/latex/base/unpack.ins +2020/12/31 | 399035 | macros/latex/base/usrguide.pdf +2020/12/31 | 68428 | macros/latex/base/usrguide.tex +2020/12/31 | 89386 | macros/latex/base/utf8ienc.dtx +2020/12/31 | 331074 | macros/latex/base/utf8ienc.pdf +2020/12/31 | 10053 | macros/latex/base/webcomp.err +2020/12/31 | 136159 | macros/latex/base/webcomp.pdf +2020/12/31 | 27943154 | macros/latex/base.zip 2005/04/09 | 16501 | macros/latex/contrib/12many/12many.dtx 2005/04/09 | 1219 | macros/latex/contrib/12many/12many.ins 2005/04/09 | 393999 | macros/latex/contrib/12many/12many.pdf @@ -188800,10 +188799,10 @@ 2020/03/03 | 19106 | macros/latex/contrib/biblatex2bibitem/LICENSE.txt 2020/03/03 | 3040 | macros/latex/contrib/biblatex2bibitem/README.md 2020/03/03 | 130703 | macros/latex/contrib/biblatex2bibitem.zip -2020/08/23 | 132465 | macros/latex/contrib/biblatex/biber/bltxml/biblatex-examples.bltxml -2020/08/23 | 68013 | macros/latex/contrib/biblatex/bibtex/bib/biblatex/biblatex-examples.bib -2020/08/23 | 65407 | macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst -2020/08/23 | 44443 | macros/latex/contrib/biblatex/CHANGES.md +2020/12/31 | 132465 | macros/latex/contrib/biblatex/biber/bltxml/biblatex-examples.bltxml +2020/12/31 | 68013 | macros/latex/contrib/biblatex/bibtex/bib/biblatex/biblatex-examples.bib +2020/12/31 | 65407 | macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst +2020/12/31 | 45570 | macros/latex/contrib/biblatex/CHANGES.md 2020/08/08 | 809609 | macros/latex/contrib/biblatex-contrib/archaeologie/archaeologie.dtx 2020/08/08 | 1191830 | macros/latex/contrib/biblatex-contrib/archaeologie/archaeologie.pdf 2020/08/08 | 2204 | macros/latex/contrib/biblatex-contrib/archaeologie/Makefile @@ -189841,279 +189840,277 @@ 2020/11/11 | 17248 | macros/latex/contrib/biblatex-contrib/windycity/windycity.cbx 2020/11/11 | 503 | macros/latex/contrib/biblatex-contrib/windycity/windycity.dbx 2020/11/11 | 509095 | macros/latex/contrib/biblatex-contrib/windycity.zip -2020/08/23 | 1588759 | macros/latex/contrib/biblatex/doc/biblatex.pdf -2020/08/23 | 1029383 | macros/latex/contrib/biblatex/doc/biblatex.tex -2020/08/23 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-biber.pdf -2020/08/23 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-bibtex.pdf -2020/08/23 | 5175 | macros/latex/contrib/biblatex/doc/examples/01-introduction.tex -2020/08/23 | 207853 | macros/latex/contrib/biblatex/doc/examples/02-annotations-biber.pdf -2020/08/23 | 207478 | macros/latex/contrib/biblatex/doc/examples/02-annotations-bibtex.pdf -2020/08/23 | 545 | macros/latex/contrib/biblatex/doc/examples/02-annotations.tex -2020/08/23 | 246343 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf -2020/08/23 | 245414 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf -2020/08/23 | 38925 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex -2020/08/23 | 80156 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-biber.pdf -2020/08/23 | 80152 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-bibtex.pdf -2020/08/23 | 2395 | macros/latex/contrib/biblatex/doc/examples/04-delimiters.tex -2020/08/23 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-biber.pdf -2020/08/23 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-bibtex.pdf -2020/08/23 | 1994 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section.tex -2020/08/23 | 98395 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-biber.pdf -2020/08/23 | 98390 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-bibtex.pdf -2020/08/23 | 1876 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section.tex -2020/08/23 | 98442 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-biber.pdf -2020/08/23 | 98437 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-bibtex.pdf -2020/08/23 | 1340 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment.tex -2020/08/23 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-biber.pdf -2020/08/23 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-bibtex.pdf -2020/08/23 | 1311 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword.tex -2020/08/23 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-biber.pdf -2020/08/23 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-bibtex.pdf -2020/08/23 | 1682 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category.tex -2020/08/23 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-biber.pdf -2020/08/23 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-bibtex.pdf -2020/08/23 | 783 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type.tex -2020/08/23 | 157684 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-biber.pdf -2020/08/23 | 156536 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf -2020/08/23 | 1863 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.tex -2020/08/23 | 1942 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1.tex -2020/08/23 | 157659 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-biber.pdf -2020/08/23 | 156527 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf -2020/08/23 | 1206 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.tex -2020/08/23 | 1287 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2.tex -2020/08/23 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-biber.pdf -2020/08/23 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-bibtex.pdf -2020/08/23 | 2899 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid.tex -2020/08/23 | 158307 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-biber.pdf -2020/08/23 | 157502 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf -2020/08/23 | 1455 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.tex -2020/08/23 | 1409 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed.tex -2020/08/23 | 170519 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-biber.pdf -2020/08/23 | 169812 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-bibtex.pdf -2020/08/23 | 2434 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single.tex -2020/08/23 | 171712 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-biber.pdf -2020/08/23 | 171031 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-bibtex.pdf -2020/08/23 | 5091 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple.tex -2020/08/23 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-biber.pdf -2020/08/23 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-bibtex.pdf -2020/08/23 | 3588 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry.tex -2020/08/23 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-biber.pdf -2020/08/23 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-bibtex.pdf -2020/08/23 | 2688 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric.tex -2020/08/23 | 186808 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-biber.pdf -2020/08/23 | 187105 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-bibtex.pdf -2020/08/23 | 3036 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp.tex -2020/08/23 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-biber.pdf -2020/08/23 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-bibtex.pdf -2020/08/23 | 1546 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb.tex -2020/08/23 | 200075 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-biber.pdf -2020/08/23 | 199318 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-bibtex.pdf -2020/08/23 | 1988 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic.tex -2020/08/23 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-biber.pdf -2020/08/23 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-bibtex.pdf -2020/08/23 | 744 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb.tex -2020/08/23 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-biber.pdf -2020/08/23 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-bibtex.pdf -2020/08/23 | 757 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template.tex -2020/08/23 | 280078 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-biber.pdf -2020/08/23 | 277799 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-bibtex.pdf -2020/08/23 | 7710 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear.tex -2020/08/23 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-biber.pdf -2020/08/23 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-bibtex.pdf -2020/08/23 | 7478 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid.tex -2020/08/23 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-biber.pdf -2020/08/23 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-bibtex.pdf -2020/08/23 | 5780 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp.tex -2020/08/23 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-biber.pdf -2020/08/23 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-bibtex.pdf -2020/08/23 | 7288 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp.tex -2020/08/23 | 277795 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-biber.pdf -2020/08/23 | 275259 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-bibtex.pdf -2020/08/23 | 3713 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle.tex -2020/08/23 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-biber.pdf -2020/08/23 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-bibtex.pdf -2020/08/23 | 3206 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid.tex -2020/08/23 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-biber.pdf -2020/08/23 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-bibtex.pdf -2020/08/23 | 1334 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp.tex -2020/08/23 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-biber.pdf -2020/08/23 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-bibtex.pdf -2020/08/23 | 2833 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp.tex -2020/08/23 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-biber.pdf -2020/08/23 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-bibtex.pdf -2020/08/23 | 2635 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse.tex -2020/08/23 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-biber.pdf -2020/08/23 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-bibtex.pdf -2020/08/23 | 1346 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp.tex -2020/08/23 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-biber.pdf -2020/08/23 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-bibtex.pdf -2020/08/23 | 2585 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp.tex -2020/08/23 | 268065 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-biber.pdf -2020/08/23 | 266542 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-bibtex.pdf -2020/08/23 | 5047 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose.tex -2020/08/23 | 272064 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-biber.pdf -2020/08/23 | 270652 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-bibtex.pdf -2020/08/23 | 7002 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid.tex -2020/08/23 | 270391 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-biber.pdf -2020/08/23 | 268908 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-bibtex.pdf -2020/08/23 | 5888 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note.tex -2020/08/23 | 274164 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-biber.pdf -2020/08/23 | 272786 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-bibtex.pdf -2020/08/23 | 8029 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote.tex -2020/08/23 | 328754 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-biber.pdf -2020/08/23 | 327370 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-bibtex.pdf -2020/08/23 | 14153 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1.tex -2020/08/23 | 273584 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-biber.pdf -2020/08/23 | 272203 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-bibtex.pdf -2020/08/23 | 9725 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2.tex -2020/08/23 | 270799 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-biber.pdf -2020/08/23 | 269420 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-bibtex.pdf -2020/08/23 | 8115 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3.tex -2020/08/23 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-biber.pdf -2020/08/23 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-bibtex.pdf -2020/08/23 | 2580 | macros/latex/contrib/biblatex/doc/examples/80-style-reading.tex -2020/08/23 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-biber.pdf -2020/08/23 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-bibtex.pdf -2020/08/23 | 791 | macros/latex/contrib/biblatex/doc/examples/81-style-draft.tex -2020/08/23 | 150179 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf -2020/08/23 | 148860 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-bibtex.pdf -2020/08/23 | 840 | macros/latex/contrib/biblatex/doc/examples/82-style-debug.tex -2020/08/23 | 31281 | macros/latex/contrib/biblatex/doc/examples/90-related-entries-biber.pdf -2020/08/23 | 391 | macros/latex/contrib/biblatex/doc/examples/90-related-entries.tex -2020/08/23 | 21707 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes-biber.pdf -2020/08/23 | 810 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes.tex -2020/08/23 | 63376 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists-biber.pdf -2020/08/23 | 1549 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists.tex -2020/08/23 | 37768 | macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf -2020/08/23 | 102 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.dbx -2020/08/23 | 12770 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex -2020/08/23 | 24027 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix-biber.pdf -2020/08/23 | 3520 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix.tex -2020/08/23 | 505 | macros/latex/contrib/biblatex/doc/examples/95-customlists.bib -2020/08/23 | 12296 | macros/latex/contrib/biblatex/doc/examples/95-customlists-biber.pdf -2020/08/23 | 159 | macros/latex/contrib/biblatex/doc/examples/95-customlists.dbx -2020/08/23 | 3273 | macros/latex/contrib/biblatex/doc/examples/95-customlists.tex -2020/08/23 | 25296 | macros/latex/contrib/biblatex/doc/examples/96-dates-biber.pdf -2020/08/23 | 7769 | macros/latex/contrib/biblatex/doc/examples/96-dates.tex -2020/08/23 | 426 | macros/latex/contrib/biblatex/doc/examples/97-annotations.bib -2020/08/23 | 16647 | macros/latex/contrib/biblatex/doc/examples/97-annotations-biber.pdf -2020/08/23 | 1800 | macros/latex/contrib/biblatex/doc/examples/97-annotations.tex -2020/08/23 | 68013 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bib -2020/08/23 | 132465 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bltxml -2020/08/23 | 1731 | macros/latex/contrib/biblatex/latex/bbx/alphabetic.bbx -2020/08/23 | 98 | macros/latex/contrib/biblatex/latex/bbx/alphabetic-verb.bbx -2020/08/23 | 3437 | macros/latex/contrib/biblatex/latex/bbx/authortitle.bbx -2020/08/23 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-comp.bbx -2020/08/23 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ibid.bbx -2020/08/23 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-icomp.bbx -2020/08/23 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-tcomp.bbx -2020/08/23 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-terse.bbx -2020/08/23 | 102 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ticomp.bbx -2020/08/23 | 8024 | macros/latex/contrib/biblatex/latex/bbx/authoryear.bbx -2020/08/23 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-comp.bbx -2020/08/23 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-ibid.bbx -2020/08/23 | 99 | macros/latex/contrib/biblatex/latex/bbx/authoryear-icomp.bbx -2020/08/23 | 4032 | macros/latex/contrib/biblatex/latex/bbx/debug.bbx -2020/08/23 | 1029 | macros/latex/contrib/biblatex/latex/bbx/draft.bbx -2020/08/23 | 1687 | macros/latex/contrib/biblatex/latex/bbx/numeric.bbx -2020/08/23 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-comp.bbx -2020/08/23 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-verb.bbx -2020/08/23 | 4480 | macros/latex/contrib/biblatex/latex/bbx/reading.bbx -2020/08/23 | 25668 | macros/latex/contrib/biblatex/latex/bbx/standard.bbx -2020/08/23 | 91 | macros/latex/contrib/biblatex/latex/bbx/verbose.bbx -2020/08/23 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-ibid.bbx -2020/08/23 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-inote.bbx -2020/08/23 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-note.bbx -2020/08/23 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad1.bbx -2020/08/23 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad2.bbx -2020/08/23 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad3.bbx -2020/08/23 | 69 | macros/latex/contrib/biblatex/latex/biblatex.cfg -2020/08/23 | 90799 | macros/latex/contrib/biblatex/latex/biblatex.def -2020/08/23 | 498507 | macros/latex/contrib/biblatex/latex/biblatex.sty -2020/08/23 | 24155 | macros/latex/contrib/biblatex/latex/blx-bibtex.def -2020/08/23 | 7875 | macros/latex/contrib/biblatex/latex/blx-case-expl3.def -2020/08/23 | 7221 | macros/latex/contrib/biblatex/latex/blx-case-latex2e.def -2020/08/23 | 13243 | macros/latex/contrib/biblatex/latex/blx-compat.def -2020/08/23 | 32524 | macros/latex/contrib/biblatex/latex/blx-dm.def -2020/08/23 | 2126 | macros/latex/contrib/biblatex/latex/blx-mcite.def -2020/08/23 | 2190 | macros/latex/contrib/biblatex/latex/blx-natbib.def -2020/08/23 | 3280 | macros/latex/contrib/biblatex/latex/blx-unicode.def -2020/08/23 | 4261 | macros/latex/contrib/biblatex/latex/cbx/alphabetic.cbx -2020/08/23 | 2257 | macros/latex/contrib/biblatex/latex/cbx/alphabetic-verb.cbx -2020/08/23 | 2893 | macros/latex/contrib/biblatex/latex/cbx/authortitle.cbx -2020/08/23 | 5661 | macros/latex/contrib/biblatex/latex/cbx/authortitle-comp.cbx -2020/08/23 | 3850 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ibid.cbx -2020/08/23 | 6648 | macros/latex/contrib/biblatex/latex/cbx/authortitle-icomp.cbx -2020/08/23 | 2934 | macros/latex/contrib/biblatex/latex/cbx/authortitle-tcomp.cbx -2020/08/23 | 1284 | macros/latex/contrib/biblatex/latex/cbx/authortitle-terse.cbx -2020/08/23 | 3454 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ticomp.cbx -2020/08/23 | 3976 | macros/latex/contrib/biblatex/latex/cbx/authoryear.cbx -2020/08/23 | 8737 | macros/latex/contrib/biblatex/latex/cbx/authoryear-comp.cbx -2020/08/23 | 5131 | macros/latex/contrib/biblatex/latex/cbx/authoryear-ibid.cbx -2020/08/23 | 9853 | macros/latex/contrib/biblatex/latex/cbx/authoryear-icomp.cbx -2020/08/23 | 2388 | macros/latex/contrib/biblatex/latex/cbx/debug.cbx -2020/08/23 | 1808 | macros/latex/contrib/biblatex/latex/cbx/draft.cbx -2020/08/23 | 4578 | macros/latex/contrib/biblatex/latex/cbx/numeric.cbx -2020/08/23 | 10374 | macros/latex/contrib/biblatex/latex/cbx/numeric-comp.cbx -2020/08/23 | 2572 | macros/latex/contrib/biblatex/latex/cbx/numeric-verb.cbx -2020/08/23 | 87 | macros/latex/contrib/biblatex/latex/cbx/reading.cbx -2020/08/23 | 7000 | macros/latex/contrib/biblatex/latex/cbx/verbose.cbx -2020/08/23 | 7801 | macros/latex/contrib/biblatex/latex/cbx/verbose-ibid.cbx -2020/08/23 | 9620 | macros/latex/contrib/biblatex/latex/cbx/verbose-inote.cbx -2020/08/23 | 8688 | macros/latex/contrib/biblatex/latex/cbx/verbose-note.cbx -2020/08/23 | 9091 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad1.cbx -2020/08/23 | 8784 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad2.cbx -2020/08/23 | 7936 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad3.cbx -2020/08/23 | 169 | macros/latex/contrib/biblatex/latex/lbx/american.lbx -2020/08/23 | 782 | macros/latex/contrib/biblatex/latex/lbx/australian.lbx -2020/08/23 | 276 | macros/latex/contrib/biblatex/latex/lbx/austrian.lbx -2020/08/23 | 29100 | macros/latex/contrib/biblatex/latex/lbx/brazilian.lbx -2020/08/23 | 128 | macros/latex/contrib/biblatex/latex/lbx/brazil.lbx -2020/08/23 | 2893 | macros/latex/contrib/biblatex/latex/lbx/british.lbx -2020/08/23 | 44468 | macros/latex/contrib/biblatex/latex/lbx/bulgarian.lbx -2020/08/23 | 163 | macros/latex/contrib/biblatex/latex/lbx/canadian.lbx -2020/08/23 | 35569 | macros/latex/contrib/biblatex/latex/lbx/catalan.lbx -2020/08/23 | 29072 | macros/latex/contrib/biblatex/latex/lbx/croatian.lbx -2020/08/23 | 33062 | macros/latex/contrib/biblatex/latex/lbx/czech.lbx -2020/08/23 | 30087 | macros/latex/contrib/biblatex/latex/lbx/danish.lbx -2020/08/23 | 30596 | macros/latex/contrib/biblatex/latex/lbx/dutch.lbx -2020/08/23 | 38458 | macros/latex/contrib/biblatex/latex/lbx/english.lbx -2020/08/23 | 33007 | macros/latex/contrib/biblatex/latex/lbx/estonian.lbx -2020/08/23 | 36663 | macros/latex/contrib/biblatex/latex/lbx/finnish.lbx -2020/08/23 | 34500 | macros/latex/contrib/biblatex/latex/lbx/french.lbx -2020/08/23 | 28621 | macros/latex/contrib/biblatex/latex/lbx/galician.lbx -2020/08/23 | 32887 | macros/latex/contrib/biblatex/latex/lbx/german.lbx -2020/08/23 | 35299 | macros/latex/contrib/biblatex/latex/lbx/greek.lbx -2020/08/23 | 125 | macros/latex/contrib/biblatex/latex/lbx/hungarian.lbx -2020/08/23 | 25609 | macros/latex/contrib/biblatex/latex/lbx/icelandic.lbx -2020/08/23 | 23181 | macros/latex/contrib/biblatex/latex/lbx/italian.lbx -2020/08/23 | 43608 | macros/latex/contrib/biblatex/latex/lbx/latvian.lbx -2020/08/23 | 44740 | macros/latex/contrib/biblatex/latex/lbx/lithuanian.lbx -2020/08/23 | 39038 | macros/latex/contrib/biblatex/latex/lbx/magyar.lbx -2020/08/23 | 571 | macros/latex/contrib/biblatex/latex/lbx/naustrian.lbx -2020/08/23 | 856 | macros/latex/contrib/biblatex/latex/lbx/newzealand.lbx -2020/08/23 | 520 | macros/latex/contrib/biblatex/latex/lbx/ngerman.lbx -2020/08/23 | 29247 | macros/latex/contrib/biblatex/latex/lbx/norsk.lbx -2020/08/23 | 769 | macros/latex/contrib/biblatex/latex/lbx/nswissgerman.lbx -2020/08/23 | 19781 | macros/latex/contrib/biblatex/latex/lbx/nynorsk.lbx -2020/08/23 | 31993 | macros/latex/contrib/biblatex/latex/lbx/polish.lbx -2020/08/23 | 132 | macros/latex/contrib/biblatex/latex/lbx/portuges.lbx -2020/08/23 | 29318 | macros/latex/contrib/biblatex/latex/lbx/portuguese.lbx -2020/08/23 | 45070 | macros/latex/contrib/biblatex/latex/lbx/russian.lbx -2020/08/23 | 33082 | macros/latex/contrib/biblatex/latex/lbx/serbianc.lbx -2020/08/23 | 23858 | macros/latex/contrib/biblatex/latex/lbx/serbian.lbx -2020/08/23 | 32154 | macros/latex/contrib/biblatex/latex/lbx/slovak.lbx -2020/08/23 | 31273 | macros/latex/contrib/biblatex/latex/lbx/slovene.lbx -2020/08/23 | 127 | macros/latex/contrib/biblatex/latex/lbx/slovenian.lbx -2020/08/23 | 47020 | macros/latex/contrib/biblatex/latex/lbx/spanish.lbx -2020/08/23 | 26169 | macros/latex/contrib/biblatex/latex/lbx/swedish.lbx -2020/08/23 | 474 | macros/latex/contrib/biblatex/latex/lbx/swissgerman.lbx -2020/08/23 | 31124 | macros/latex/contrib/biblatex/latex/lbx/turkish.lbx -2020/08/23 | 127 | macros/latex/contrib/biblatex/latex/lbx/UKenglish.lbx -2020/08/23 | 44157 | macros/latex/contrib/biblatex/latex/lbx/ukrainian.lbx -2020/08/23 | 129 | macros/latex/contrib/biblatex/latex/lbx/USenglish.lbx -2020/08/23 | 5197 | macros/latex/contrib/biblatex/README -2020/08/23 | 18660244 | macros/latex/contrib/biblatex.zip +2020/12/31 | 1598244 | macros/latex/contrib/biblatex/doc/biblatex.pdf +2020/12/31 | 1034510 | macros/latex/contrib/biblatex/doc/biblatex.tex +2020/12/31 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-biber.pdf +2020/12/31 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-bibtex.pdf +2020/12/31 | 5175 | macros/latex/contrib/biblatex/doc/examples/01-introduction.tex +2020/12/31 | 207853 | macros/latex/contrib/biblatex/doc/examples/02-annotations-biber.pdf +2020/12/31 | 207478 | macros/latex/contrib/biblatex/doc/examples/02-annotations-bibtex.pdf +2020/12/31 | 545 | macros/latex/contrib/biblatex/doc/examples/02-annotations.tex +2020/12/31 | 246067 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf +2020/12/31 | 245466 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf +2020/12/31 | 39026 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex +2020/12/31 | 80156 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-biber.pdf +2020/12/31 | 80152 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-bibtex.pdf +2020/12/31 | 2395 | macros/latex/contrib/biblatex/doc/examples/04-delimiters.tex +2020/12/31 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-biber.pdf +2020/12/31 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-bibtex.pdf +2020/12/31 | 1994 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section.tex +2020/12/31 | 98395 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-biber.pdf +2020/12/31 | 98390 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-bibtex.pdf +2020/12/31 | 1876 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section.tex +2020/12/31 | 98442 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-biber.pdf +2020/12/31 | 98437 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-bibtex.pdf +2020/12/31 | 1340 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment.tex +2020/12/31 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-biber.pdf +2020/12/31 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-bibtex.pdf +2020/12/31 | 1311 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword.tex +2020/12/31 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-biber.pdf +2020/12/31 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-bibtex.pdf +2020/12/31 | 1682 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category.tex +2020/12/31 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-biber.pdf +2020/12/31 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-bibtex.pdf +2020/12/31 | 783 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type.tex +2020/12/31 | 157684 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-biber.pdf +2020/12/31 | 156540 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf +2020/12/31 | 1942 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1.tex +2020/12/31 | 157659 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-biber.pdf +2020/12/31 | 156540 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf +2020/12/31 | 1287 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2.tex +2020/12/31 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-biber.pdf +2020/12/31 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-bibtex.pdf +2020/12/31 | 2899 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid.tex +2020/12/31 | 158307 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-biber.pdf +2020/12/31 | 157616 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf +2020/12/31 | 1409 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed.tex +2020/12/31 | 170519 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-biber.pdf +2020/12/31 | 169812 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-bibtex.pdf +2020/12/31 | 2434 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single.tex +2020/12/31 | 171712 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-biber.pdf +2020/12/31 | 171031 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-bibtex.pdf +2020/12/31 | 5091 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple.tex +2020/12/31 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-biber.pdf +2020/12/31 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-bibtex.pdf +2020/12/31 | 3588 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry.tex +2020/12/31 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-biber.pdf +2020/12/31 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-bibtex.pdf +2020/12/31 | 2688 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric.tex +2020/12/31 | 186808 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-biber.pdf +2020/12/31 | 187105 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-bibtex.pdf +2020/12/31 | 3036 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp.tex +2020/12/31 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-biber.pdf +2020/12/31 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-bibtex.pdf +2020/12/31 | 1546 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb.tex +2020/12/31 | 200075 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-biber.pdf +2020/12/31 | 199318 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-bibtex.pdf +2020/12/31 | 1988 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic.tex +2020/12/31 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-biber.pdf +2020/12/31 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-bibtex.pdf +2020/12/31 | 744 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb.tex +2020/12/31 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-biber.pdf +2020/12/31 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-bibtex.pdf +2020/12/31 | 757 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template.tex +2020/12/31 | 280078 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-biber.pdf +2020/12/31 | 277799 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-bibtex.pdf +2020/12/31 | 7710 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear.tex +2020/12/31 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-biber.pdf +2020/12/31 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-bibtex.pdf +2020/12/31 | 7478 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid.tex +2020/12/31 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-biber.pdf +2020/12/31 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-bibtex.pdf +2020/12/31 | 5780 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp.tex +2020/12/31 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-biber.pdf +2020/12/31 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-bibtex.pdf +2020/12/31 | 7288 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp.tex +2020/12/31 | 277795 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-biber.pdf +2020/12/31 | 275259 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-bibtex.pdf +2020/12/31 | 3713 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle.tex +2020/12/31 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-biber.pdf +2020/12/31 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-bibtex.pdf +2020/12/31 | 3206 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid.tex +2020/12/31 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-biber.pdf +2020/12/31 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-bibtex.pdf +2020/12/31 | 1334 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp.tex +2020/12/31 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-biber.pdf +2020/12/31 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-bibtex.pdf +2020/12/31 | 2833 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp.tex +2020/12/31 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-biber.pdf +2020/12/31 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-bibtex.pdf +2020/12/31 | 2635 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse.tex +2020/12/31 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-biber.pdf +2020/12/31 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-bibtex.pdf +2020/12/31 | 1346 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp.tex +2020/12/31 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-biber.pdf +2020/12/31 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-bibtex.pdf +2020/12/31 | 2585 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp.tex +2020/12/31 | 268065 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-biber.pdf +2020/12/31 | 266542 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-bibtex.pdf +2020/12/31 | 5047 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose.tex +2020/12/31 | 272064 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-biber.pdf +2020/12/31 | 270652 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-bibtex.pdf +2020/12/31 | 7002 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid.tex +2020/12/31 | 270391 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-biber.pdf +2020/12/31 | 268908 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-bibtex.pdf +2020/12/31 | 5888 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note.tex +2020/12/31 | 274164 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-biber.pdf +2020/12/31 | 272786 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-bibtex.pdf +2020/12/31 | 8029 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote.tex +2020/12/31 | 328754 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-biber.pdf +2020/12/31 | 327370 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-bibtex.pdf +2020/12/31 | 14153 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1.tex +2020/12/31 | 273584 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-biber.pdf +2020/12/31 | 272203 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-bibtex.pdf +2020/12/31 | 9725 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2.tex +2020/12/31 | 270799 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-biber.pdf +2020/12/31 | 269420 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-bibtex.pdf +2020/12/31 | 8115 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3.tex +2020/12/31 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-biber.pdf +2020/12/31 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-bibtex.pdf +2020/12/31 | 2580 | macros/latex/contrib/biblatex/doc/examples/80-style-reading.tex +2020/12/31 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-biber.pdf +2020/12/31 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-bibtex.pdf +2020/12/31 | 791 | macros/latex/contrib/biblatex/doc/examples/81-style-draft.tex +2020/12/31 | 149679 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf +2020/12/31 | 148860 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-bibtex.pdf +2020/12/31 | 840 | macros/latex/contrib/biblatex/doc/examples/82-style-debug.tex +2020/12/31 | 31281 | macros/latex/contrib/biblatex/doc/examples/90-related-entries-biber.pdf +2020/12/31 | 391 | macros/latex/contrib/biblatex/doc/examples/90-related-entries.tex +2020/12/31 | 21707 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes-biber.pdf +2020/12/31 | 810 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes.tex +2020/12/31 | 63376 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists-biber.pdf +2020/12/31 | 1549 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists.tex +2020/12/31 | 39823 | macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf +2020/12/31 | 102 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.dbx +2020/12/31 | 12400 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex +2020/12/31 | 24027 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix-biber.pdf +2020/12/31 | 3520 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix.tex +2020/12/31 | 505 | macros/latex/contrib/biblatex/doc/examples/95-customlists.bib +2020/12/31 | 12296 | macros/latex/contrib/biblatex/doc/examples/95-customlists-biber.pdf +2020/12/31 | 159 | macros/latex/contrib/biblatex/doc/examples/95-customlists.dbx +2020/12/31 | 3273 | macros/latex/contrib/biblatex/doc/examples/95-customlists.tex +2020/12/31 | 25296 | macros/latex/contrib/biblatex/doc/examples/96-dates-biber.pdf +2020/12/31 | 7750 | macros/latex/contrib/biblatex/doc/examples/96-dates.tex +2020/12/31 | 426 | macros/latex/contrib/biblatex/doc/examples/97-annotations.bib +2020/12/31 | 16647 | macros/latex/contrib/biblatex/doc/examples/97-annotations-biber.pdf +2020/12/31 | 1781 | macros/latex/contrib/biblatex/doc/examples/97-annotations.tex +2020/12/31 | 68013 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bib +2020/12/31 | 132465 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bltxml +2020/12/31 | 1731 | macros/latex/contrib/biblatex/latex/bbx/alphabetic.bbx +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/alphabetic-verb.bbx +2020/12/31 | 3437 | macros/latex/contrib/biblatex/latex/bbx/authortitle.bbx +2020/12/31 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-comp.bbx +2020/12/31 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ibid.bbx +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-icomp.bbx +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-tcomp.bbx +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-terse.bbx +2020/12/31 | 102 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ticomp.bbx +2020/12/31 | 8024 | macros/latex/contrib/biblatex/latex/bbx/authoryear.bbx +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-comp.bbx +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-ibid.bbx +2020/12/31 | 99 | macros/latex/contrib/biblatex/latex/bbx/authoryear-icomp.bbx +2020/12/31 | 4032 | macros/latex/contrib/biblatex/latex/bbx/debug.bbx +2020/12/31 | 1160 | macros/latex/contrib/biblatex/latex/bbx/draft.bbx +2020/12/31 | 1818 | macros/latex/contrib/biblatex/latex/bbx/numeric.bbx +2020/12/31 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-comp.bbx +2020/12/31 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-verb.bbx +2020/12/31 | 4611 | macros/latex/contrib/biblatex/latex/bbx/reading.bbx +2020/12/31 | 25680 | macros/latex/contrib/biblatex/latex/bbx/standard.bbx +2020/12/31 | 91 | macros/latex/contrib/biblatex/latex/bbx/verbose.bbx +2020/12/31 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-ibid.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-inote.bbx +2020/12/31 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-note.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad1.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad2.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad3.bbx +2020/12/31 | 69 | macros/latex/contrib/biblatex/latex/biblatex.cfg +2020/12/31 | 91946 | macros/latex/contrib/biblatex/latex/biblatex.def +2020/12/31 | 506356 | macros/latex/contrib/biblatex/latex/biblatex.sty +2020/12/31 | 24371 | macros/latex/contrib/biblatex/latex/blx-bibtex.def +2020/12/31 | 8433 | macros/latex/contrib/biblatex/latex/blx-case-expl3.sty +2020/12/31 | 8363 | macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty +2020/12/31 | 13379 | macros/latex/contrib/biblatex/latex/blx-compat.def +2020/12/31 | 32359 | macros/latex/contrib/biblatex/latex/blx-dm.def +2020/12/31 | 2126 | macros/latex/contrib/biblatex/latex/blx-mcite.def +2020/12/31 | 2190 | macros/latex/contrib/biblatex/latex/blx-natbib.def +2020/12/31 | 3786 | macros/latex/contrib/biblatex/latex/blx-unicode.def +2020/12/31 | 4261 | macros/latex/contrib/biblatex/latex/cbx/alphabetic.cbx +2020/12/31 | 2257 | macros/latex/contrib/biblatex/latex/cbx/alphabetic-verb.cbx +2020/12/31 | 2893 | macros/latex/contrib/biblatex/latex/cbx/authortitle.cbx +2020/12/31 | 5661 | macros/latex/contrib/biblatex/latex/cbx/authortitle-comp.cbx +2020/12/31 | 3850 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ibid.cbx +2020/12/31 | 6648 | macros/latex/contrib/biblatex/latex/cbx/authortitle-icomp.cbx +2020/12/31 | 2934 | macros/latex/contrib/biblatex/latex/cbx/authortitle-tcomp.cbx +2020/12/31 | 1284 | macros/latex/contrib/biblatex/latex/cbx/authortitle-terse.cbx +2020/12/31 | 3454 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ticomp.cbx +2020/12/31 | 3976 | macros/latex/contrib/biblatex/latex/cbx/authoryear.cbx +2020/12/31 | 8737 | macros/latex/contrib/biblatex/latex/cbx/authoryear-comp.cbx +2020/12/31 | 5131 | macros/latex/contrib/biblatex/latex/cbx/authoryear-ibid.cbx +2020/12/31 | 9853 | macros/latex/contrib/biblatex/latex/cbx/authoryear-icomp.cbx +2020/12/31 | 2388 | macros/latex/contrib/biblatex/latex/cbx/debug.cbx +2020/12/31 | 1808 | macros/latex/contrib/biblatex/latex/cbx/draft.cbx +2020/12/31 | 4578 | macros/latex/contrib/biblatex/latex/cbx/numeric.cbx +2020/12/31 | 10374 | macros/latex/contrib/biblatex/latex/cbx/numeric-comp.cbx +2020/12/31 | 2572 | macros/latex/contrib/biblatex/latex/cbx/numeric-verb.cbx +2020/12/31 | 87 | macros/latex/contrib/biblatex/latex/cbx/reading.cbx +2020/12/31 | 7000 | macros/latex/contrib/biblatex/latex/cbx/verbose.cbx +2020/12/31 | 7801 | macros/latex/contrib/biblatex/latex/cbx/verbose-ibid.cbx +2020/12/31 | 9620 | macros/latex/contrib/biblatex/latex/cbx/verbose-inote.cbx +2020/12/31 | 8688 | macros/latex/contrib/biblatex/latex/cbx/verbose-note.cbx +2020/12/31 | 9091 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad1.cbx +2020/12/31 | 8784 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad2.cbx +2020/12/31 | 7936 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad3.cbx +2020/12/31 | 169 | macros/latex/contrib/biblatex/latex/lbx/american.lbx +2020/12/31 | 782 | macros/latex/contrib/biblatex/latex/lbx/australian.lbx +2020/12/31 | 276 | macros/latex/contrib/biblatex/latex/lbx/austrian.lbx +2020/12/31 | 30679 | macros/latex/contrib/biblatex/latex/lbx/basque.lbx +2020/12/31 | 29100 | macros/latex/contrib/biblatex/latex/lbx/brazilian.lbx +2020/12/31 | 128 | macros/latex/contrib/biblatex/latex/lbx/brazil.lbx +2020/12/31 | 2893 | macros/latex/contrib/biblatex/latex/lbx/british.lbx +2020/12/31 | 44468 | macros/latex/contrib/biblatex/latex/lbx/bulgarian.lbx +2020/12/31 | 163 | macros/latex/contrib/biblatex/latex/lbx/canadian.lbx +2020/12/31 | 35308 | macros/latex/contrib/biblatex/latex/lbx/catalan.lbx +2020/12/31 | 29072 | macros/latex/contrib/biblatex/latex/lbx/croatian.lbx +2020/12/31 | 33062 | macros/latex/contrib/biblatex/latex/lbx/czech.lbx +2020/12/31 | 30087 | macros/latex/contrib/biblatex/latex/lbx/danish.lbx +2020/12/31 | 30596 | macros/latex/contrib/biblatex/latex/lbx/dutch.lbx +2020/12/31 | 38558 | macros/latex/contrib/biblatex/latex/lbx/english.lbx +2020/12/31 | 33007 | macros/latex/contrib/biblatex/latex/lbx/estonian.lbx +2020/12/31 | 36663 | macros/latex/contrib/biblatex/latex/lbx/finnish.lbx +2020/12/31 | 34452 | macros/latex/contrib/biblatex/latex/lbx/french.lbx +2020/12/31 | 28621 | macros/latex/contrib/biblatex/latex/lbx/galician.lbx +2020/12/31 | 32997 | macros/latex/contrib/biblatex/latex/lbx/german.lbx +2020/12/31 | 35299 | macros/latex/contrib/biblatex/latex/lbx/greek.lbx +2020/12/31 | 125 | macros/latex/contrib/biblatex/latex/lbx/hungarian.lbx +2020/12/31 | 25609 | macros/latex/contrib/biblatex/latex/lbx/icelandic.lbx +2020/12/31 | 23181 | macros/latex/contrib/biblatex/latex/lbx/italian.lbx +2020/12/31 | 43608 | macros/latex/contrib/biblatex/latex/lbx/latvian.lbx +2020/12/31 | 44740 | macros/latex/contrib/biblatex/latex/lbx/lithuanian.lbx +2020/12/31 | 39038 | macros/latex/contrib/biblatex/latex/lbx/magyar.lbx +2020/12/31 | 571 | macros/latex/contrib/biblatex/latex/lbx/naustrian.lbx +2020/12/31 | 856 | macros/latex/contrib/biblatex/latex/lbx/newzealand.lbx +2020/12/31 | 520 | macros/latex/contrib/biblatex/latex/lbx/ngerman.lbx +2020/12/31 | 29247 | macros/latex/contrib/biblatex/latex/lbx/norsk.lbx +2020/12/31 | 769 | macros/latex/contrib/biblatex/latex/lbx/nswissgerman.lbx +2020/12/31 | 19781 | macros/latex/contrib/biblatex/latex/lbx/nynorsk.lbx +2020/12/31 | 31993 | macros/latex/contrib/biblatex/latex/lbx/polish.lbx +2020/12/31 | 132 | macros/latex/contrib/biblatex/latex/lbx/portuges.lbx +2020/12/31 | 29318 | macros/latex/contrib/biblatex/latex/lbx/portuguese.lbx +2020/12/31 | 45070 | macros/latex/contrib/biblatex/latex/lbx/russian.lbx +2020/12/31 | 33082 | macros/latex/contrib/biblatex/latex/lbx/serbianc.lbx +2020/12/31 | 23858 | macros/latex/contrib/biblatex/latex/lbx/serbian.lbx +2020/12/31 | 32154 | macros/latex/contrib/biblatex/latex/lbx/slovak.lbx +2020/12/31 | 31273 | macros/latex/contrib/biblatex/latex/lbx/slovene.lbx +2020/12/31 | 127 | macros/latex/contrib/biblatex/latex/lbx/slovenian.lbx +2020/12/31 | 47020 | macros/latex/contrib/biblatex/latex/lbx/spanish.lbx +2020/12/31 | 26169 | macros/latex/contrib/biblatex/latex/lbx/swedish.lbx +2020/12/31 | 474 | macros/latex/contrib/biblatex/latex/lbx/swissgerman.lbx +2020/12/31 | 31124 | macros/latex/contrib/biblatex/latex/lbx/turkish.lbx +2020/12/31 | 127 | macros/latex/contrib/biblatex/latex/lbx/UKenglish.lbx +2020/12/31 | 44157 | macros/latex/contrib/biblatex/latex/lbx/ukrainian.lbx +2020/12/31 | 129 | macros/latex/contrib/biblatex/latex/lbx/USenglish.lbx +2020/12/31 | 5197 | macros/latex/contrib/biblatex/README +2020/12/31 | 18678005 | macros/latex/contrib/biblatex.zip 2020/06/22 | 98385 | macros/latex/contrib/bibleref/bibleref.dtx 2016/09/10 | 1782 | macros/latex/contrib/bibleref/bibleref.ins 2020/06/22 | 286852 | macros/latex/contrib/bibleref/bibleref.pdf @@ -214944,45 +214941,45 @@ 2018/06/19 | 922 | macros/luatex/generic/kanaparser/kanaparser.tex 2018/06/19 | 2005 | macros/luatex/generic/kanaparser/README.md 2018/06/19 | 378065 | macros/luatex/generic/kanaparser.zip -2018/09/20 | 18092 | macros/luatex/generic/lualibs/LICENSE -2020/09/02 | 131270 | macros/luatex/generic/lualibs/lualibs-basic-merged.lua -2018/12/12 | 1850 | macros/luatex/generic/lualibs/lualibs-boolean.lua -2018/09/20 | 603 | macros/luatex/generic/lualibs/lualibs-compat.lua -2019/05/19 | 18253 | macros/luatex/generic/lualibs/lualibs-dir.lua -2020/09/02 | 27850 | macros/luatex/generic/lualibs/lualibs.dtx -2020/09/02 | 110719 | macros/luatex/generic/lualibs/lualibs-extended-merged.lua -2020/05/02 | 22175 | macros/luatex/generic/lualibs/lualibs-file.lua -2018/12/12 | 361 | macros/luatex/generic/lualibs/lualibs-function.lua -2020/05/02 | 5115 | macros/luatex/generic/lualibs/lualibs-gzip.lua -2020/05/02 | 11829 | macros/luatex/generic/lualibs/lualibs-io.lua -2020/09/02 | 38703 | macros/luatex/generic/lualibs/lualibs-lpeg.lua -2020/09/02 | 6405 | macros/luatex/generic/lualibs/lualibs-lua.lua -2018/12/12 | 2555 | macros/luatex/generic/lualibs/lualibs-math.lua -2020/05/02 | 3414 | macros/luatex/generic/lualibs/lualibs-md5.lua -2019/01/16 | 5720 | macros/luatex/generic/lualibs/lualibs-number.lua -2020/09/02 | 19323 | macros/luatex/generic/lualibs/lualibs-os.lua -2020/09/02 | 11793 | macros/luatex/generic/lualibs/lualibs-package.lua -2020/09/02 | 81574 | macros/luatex/generic/lualibs/lualibs.pdf -2018/12/12 | 1923 | macros/luatex/generic/lualibs/lualibs-set.lua -2019/07/16 | 6644 | macros/luatex/generic/lualibs/lualibs-string.lua -2020/05/02 | 41758 | macros/luatex/generic/lualibs/lualibs-table.lua -2020/09/02 | 9781 | macros/luatex/generic/lualibs/lualibs-trac-inf.lua -2020/09/02 | 41306 | macros/luatex/generic/lualibs/lualibs-unicode.lua -2018/12/12 | 14755 | macros/luatex/generic/lualibs/lualibs-url.lua -2019/06/24 | 10136 | macros/luatex/generic/lualibs/lualibs-util-deb.lua -2019/06/24 | 13625 | macros/luatex/generic/lualibs/lualibs-util-dim.lua -2018/09/27 | 9034 | macros/luatex/generic/lualibs/lualibs-util-fil.lua -2019/08/13 | 16190 | macros/luatex/generic/lualibs/lualibs-util-jsn.lua -2019/11/06 | 7149 | macros/luatex/generic/lualibs/lualibs-util-lua.lua -2020/09/02 | 24683 | macros/luatex/generic/lualibs/lualibs-util-prs.lua -2020/05/02 | 9412 | macros/luatex/generic/lualibs/lualibs-util-sta.lua -2018/12/12 | 6661 | macros/luatex/generic/lualibs/lualibs-util-sto.lua -2020/09/02 | 43947 | macros/luatex/generic/lualibs/lualibs-util-str.lua -2020/09/02 | 32815 | macros/luatex/generic/lualibs/lualibs-util-tab.lua -2019/11/06 | 7722 | macros/luatex/generic/lualibs/lualibs-util-tpl.lua -2020/09/02 | 2956 | macros/luatex/generic/lualibs/NEWS -2020/09/02 | 4740 | macros/luatex/generic/lualibs/README.md -2020/09/02 | 265756 | macros/luatex/generic/lualibs.zip +2020/01/09 | 18092 | macros/luatex/generic/lualibs/LICENSE +2020/12/31 | 131468 | macros/luatex/generic/lualibs/lualibs-basic-merged.lua +2020/01/09 | 1850 | macros/luatex/generic/lualibs/lualibs-boolean.lua +2020/01/09 | 603 | macros/luatex/generic/lualibs/lualibs-compat.lua +2020/01/09 | 18253 | macros/luatex/generic/lualibs/lualibs-dir.lua +2020/12/31 | 27850 | macros/luatex/generic/lualibs/lualibs.dtx +2020/12/31 | 110513 | macros/luatex/generic/lualibs/lualibs-extended-merged.lua +2020/12/29 | 22175 | macros/luatex/generic/lualibs/lualibs-file.lua +2020/01/09 | 361 | macros/luatex/generic/lualibs/lualibs-function.lua +2020/12/29 | 5115 | macros/luatex/generic/lualibs/lualibs-gzip.lua +2020/12/29 | 11829 | macros/luatex/generic/lualibs/lualibs-io.lua +2020/12/30 | 38703 | macros/luatex/generic/lualibs/lualibs-lpeg.lua +2020/12/30 | 6405 | macros/luatex/generic/lualibs/lualibs-lua.lua +2020/01/09 | 2555 | macros/luatex/generic/lualibs/lualibs-math.lua +2020/12/29 | 3414 | macros/luatex/generic/lualibs/lualibs-md5.lua +2020/01/09 | 5720 | macros/luatex/generic/lualibs/lualibs-number.lua +2020/12/31 | 19409 | macros/luatex/generic/lualibs/lualibs-os.lua +2020/12/31 | 11969 | macros/luatex/generic/lualibs/lualibs-package.lua +2020/12/31 | 81487 | macros/luatex/generic/lualibs/lualibs.pdf +2020/01/09 | 1923 | macros/luatex/generic/lualibs/lualibs-set.lua +2020/01/09 | 6644 | macros/luatex/generic/lualibs/lualibs-string.lua +2020/12/29 | 41758 | macros/luatex/generic/lualibs/lualibs-table.lua +2020/12/30 | 9781 | macros/luatex/generic/lualibs/lualibs-trac-inf.lua +2020/12/31 | 41306 | macros/luatex/generic/lualibs/lualibs-unicode.lua +2020/01/09 | 14755 | macros/luatex/generic/lualibs/lualibs-url.lua +2020/01/09 | 10136 | macros/luatex/generic/lualibs/lualibs-util-deb.lua +2020/12/31 | 13625 | macros/luatex/generic/lualibs/lualibs-util-dim.lua +2020/01/09 | 9034 | macros/luatex/generic/lualibs/lualibs-util-fil.lua +2020/01/09 | 16190 | macros/luatex/generic/lualibs/lualibs-util-jsn.lua +2020/01/09 | 7149 | macros/luatex/generic/lualibs/lualibs-util-lua.lua +2020/12/30 | 24683 | macros/luatex/generic/lualibs/lualibs-util-prs.lua +2020/12/29 | 9412 | macros/luatex/generic/lualibs/lualibs-util-sta.lua +2020/01/09 | 6661 | macros/luatex/generic/lualibs/lualibs-util-sto.lua +2020/12/30 | 43947 | macros/luatex/generic/lualibs/lualibs-util-str.lua +2020/12/30 | 32815 | macros/luatex/generic/lualibs/lualibs-util-tab.lua +2020/01/09 | 7722 | macros/luatex/generic/lualibs/lualibs-util-tpl.lua +2020/12/31 | 3049 | macros/luatex/generic/lualibs/NEWS +2020/12/31 | 4740 | macros/luatex/generic/lualibs/README.md +2020/12/31 | 265702 | macros/luatex/generic/lualibs.zip 2020/12/30 | 92061 | macros/luatex/generic/luamplib/luamplib.dtx 2020/12/30 | 149233 | macros/luatex/generic/luamplib/luamplib.pdf 2020/12/30 | 2752 | macros/luatex/generic/luamplib/Makefile @@ -214991,118 +214988,120 @@ 2020/12/30 | 4016 | macros/luatex/generic/luamplib/test-luamplib-latex.tex 2020/12/30 | 3872 | macros/luatex/generic/luamplib/test-luamplib-plain.tex 2020/12/30 | 182036 | macros/luatex/generic/luamplib.zip -2020/09/02 | 18714 | macros/luatex/generic/luaotfload/COPYING -2020/09/02 | 40015 | macros/luatex/generic/luaotfload/filegraph.pdf -2020/09/02 | 8602 | macros/luatex/generic/luaotfload/filegraph.tex -2020/09/02 | 861288 | macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua -2020/09/02 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua -2020/09/02 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua -2020/09/02 | 9533 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua -2020/09/02 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua -2020/09/02 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua -2020/09/02 | 89678 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua -2020/09/02 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua -2020/09/02 | 63054 | macros/luatex/generic/luaotfload/fontloader-font-con.lua -2020/09/02 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua -2020/09/02 | 154129 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua -2020/09/02 | 13382 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua -2020/09/02 | 4240 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua -2020/09/02 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua -2020/09/02 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua -2020/09/02 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua -2020/09/02 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua -2020/09/02 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua -2020/09/02 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua -2020/09/02 | 31271 | macros/luatex/generic/luaotfload/fontloader-font-one.lua -2020/09/02 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua -2020/09/02 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua -2020/09/02 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua -2020/09/02 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua -2020/09/02 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua -2020/09/02 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua -2020/09/02 | 33013 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua -2020/09/02 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua -2020/09/02 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua -2020/09/02 | 180385 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua -2020/09/02 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua -2020/09/02 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua -2020/09/02 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua -2020/09/02 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua -2020/09/02 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua -2020/09/02 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua -2020/09/02 | 13472 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua -2020/09/02 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua -2020/09/02 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua -2020/09/02 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua -2020/09/02 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua -2020/09/02 | 59378 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua -2020/09/02 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua -2020/09/02 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua -2020/09/02 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua -2020/09/02 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua -2020/09/02 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua -2020/09/02 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua -2020/09/02 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua -2020/09/02 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua -2020/09/02 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua -2020/09/02 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua -2020/09/02 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua -2020/09/02 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua -2020/09/02 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex -2020/09/02 | 962205 | macros/luatex/generic/luaotfload/fontloader-reference.lua -2020/09/02 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua -2020/09/02 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua -2020/09/02 | 31128 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua -2020/09/02 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf -2020/09/02 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua -2020/09/02 | 15990 | macros/luatex/generic/luaotfload/luaotfload-colors.lua -2020/09/02 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 -2020/09/02 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example -2020/09/02 | 31186 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua -2020/09/02 | 77426 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf -2020/09/02 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst -2020/09/02 | 134801 | macros/luatex/generic/luaotfload/luaotfload-database.lua -2020/09/02 | 21893 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua -2020/09/02 | 4991 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua -2020/09/02 | 1039 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua -2020/09/02 | 4080 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua -2020/09/02 | 28886 | macros/luatex/generic/luaotfload/luaotfload-features.lua -2020/09/02 | 25423 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua -2020/09/02 | 102477 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua -2020/09/02 | 13505 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua -2020/09/02 | 37306 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua -2020/09/02 | 18689 | macros/luatex/generic/luaotfload/luaotfload-init.lua -2020/09/02 | 486239 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf -2020/09/02 | 16688 | macros/luatex/generic/luaotfload/luaotfload-latex.tex -2020/09/02 | 18680 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua -2020/09/02 | 8875 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua -2020/09/02 | 11359 | macros/luatex/generic/luaotfload/luaotfload-log.lua -2020/09/02 | 12231 | macros/luatex/generic/luaotfload/luaotfload-main.lua -2020/09/02 | 94751 | macros/luatex/generic/luaotfload/luaotfload-main.tex -2020/09/02 | 15101 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua -2020/09/02 | 12259 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua -2020/09/02 | 31035 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua -2020/09/02 | 11020 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua -2020/09/02 | 2541 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua -2020/09/02 | 6184 | macros/luatex/generic/luaotfload/luaotfload-status.lua -2020/09/02 | 1817 | macros/luatex/generic/luaotfload/luaotfload.sty -2020/09/02 | 2617 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua -2020/09/02 | 6294 | macros/luatex/generic/luaotfload/luaotfload-szss.lua -2020/09/02 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 -2020/09/02 | 52223 | macros/luatex/generic/luaotfload/luaotfload-tool.lua -2020/09/02 | 76886 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf -2020/09/02 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst -2020/09/02 | 7563 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua -2020/09/02 | 3061 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua -2020/09/02 | 18410 | macros/luatex/generic/luaotfload/NEWS -2020/09/02 | 3784 | macros/luatex/generic/luaotfload/README.md -2020/09/02 | 21504 | macros/luatex/generic/luaotfload/scripts-demo.pdf -2020/09/02 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex -2020/09/02 | 8468 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf -2020/09/02 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex -2020/09/02 | 8392 | macros/luatex/generic/luaotfload/shaper-demo.pdf -2020/09/02 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex -2020/09/02 | 1912030 | macros/luatex/generic/luaotfload.zip +2019/12/25 | 18714 | macros/luatex/generic/luaotfload/COPYING +2020/12/31 | 40030 | macros/luatex/generic/luaotfload/filegraph.pdf +2020/12/31 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex +2020/12/31 | 863103 | macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua +2019/12/25 | 46091 | macros/luatex/generic/luaotfload/fontloader-basics-chr.lua +2020/12/31 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua +2020/12/31 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua +2020/02/03 | 5388 | macros/luatex/generic/luaotfload/fontloader-data-con.lua +2019/12/25 | 6866 | macros/luatex/generic/luaotfload/fontloader-font-afk.lua +2020/12/31 | 89678 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua +2019/12/25 | 5502 | macros/luatex/generic/luaotfload/fontloader-font-cid.lua +2020/12/31 | 63054 | macros/luatex/generic/luaotfload/fontloader-font-con.lua +2020/12/31 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua +2020/12/31 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +2020/12/31 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua +2020/12/31 | 4240 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua +2019/12/25 | 3580 | macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua +2019/12/25 | 3406 | macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua +2020/02/03 | 1794 | macros/luatex/generic/luaotfload/fontloader-font-ini.lua +2019/12/25 | 1449 | macros/luatex/generic/luaotfload/fontloader-font-lua.lua +2020/12/31 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua +2020/12/31 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua +2020/12/31 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua +2020/12/31 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua +2020/12/31 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua +2020/12/31 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua +2019/12/25 | 31802 | macros/luatex/generic/luaotfload/fontloader-font-otc.lua +2019/12/25 | 7904 | macros/luatex/generic/luaotfload/fontloader-font-oti.lua +2020/12/31 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua +2020/12/31 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua +2020/02/03 | 22966 | macros/luatex/generic/luaotfload/fontloader-font-oto.lua +2020/12/31 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua +2020/12/31 | 182024 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua +2020/12/31 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua +2020/12/31 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua +2019/12/25 | 3821 | macros/luatex/generic/luaotfload/fontloader-fonts-def.lua +2019/12/25 | 2315 | macros/luatex/generic/luaotfload/fontloader-fonts-enc.lua +2019/12/25 | 7260 | macros/luatex/generic/luaotfload/fontloader-fonts-ext.lua +2019/12/25 | 9875 | macros/luatex/generic/luaotfload/fontloader-fonts-gbn.lua +2020/12/31 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua +2019/12/25 | 57342 | macros/luatex/generic/luaotfload/fontloader-fonts-lig.lua +2019/12/25 | 912 | macros/luatex/generic/luaotfload/fontloader-fonts-mis.lua +2019/12/25 | 3674 | macros/luatex/generic/luaotfload/fontloader-fonts-syn.lua +2019/12/25 | 23399 | macros/luatex/generic/luaotfload/fontloader-fonts-tfm.lua +2020/12/31 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua +2020/12/31 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua +2019/12/25 | 1850 | macros/luatex/generic/luaotfload/fontloader-l-boolean.lua +2020/02/03 | 22175 | macros/luatex/generic/luaotfload/fontloader-l-file.lua +2019/12/25 | 361 | macros/luatex/generic/luaotfload/fontloader-l-function.lua +2020/02/03 | 11829 | macros/luatex/generic/luaotfload/fontloader-l-io.lua +2020/12/31 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua +2020/12/31 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua +2019/12/25 | 2555 | macros/luatex/generic/luaotfload/fontloader-l-math.lua +2019/12/25 | 6644 | macros/luatex/generic/luaotfload/fontloader-l-string.lua +2020/12/31 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua +2020/12/31 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua +2020/12/31 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua +2019/12/25 | 5885 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.tex +2020/12/31 | 964020 | macros/luatex/generic/luaotfload/fontloader-reference.lua +2020/12/31 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua +2020/12/31 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua +2020/12/31 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +2019/12/25 | 52 | macros/luatex/generic/luaotfload/luaotfload-blacklist.cnf +2020/12/31 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua +2020/12/31 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua +2020/12/31 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua +2020/12/31 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 +2019/12/25 | 735 | macros/luatex/generic/luaotfload/luaotfload.conf.example +2020/12/31 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua +2020/12/31 | 77331 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf +2020/12/31 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst +2020/12/31 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua +2020/12/31 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +2020/12/31 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua +2020/12/31 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua +2020/12/31 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua +2020/12/31 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua +2020/12/31 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua +2020/12/31 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +2020/12/31 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +2020/12/31 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +2020/12/31 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua +2020/12/31 | 493305 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf +2020/12/31 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex +2020/12/31 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +2020/12/31 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua +2020/12/31 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua +2020/12/31 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua +2020/12/31 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua +2020/12/31 | 98669 | macros/luatex/generic/luaotfload/luaotfload-main.tex +2020/12/31 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +2020/12/31 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua +2020/12/31 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua +2020/12/31 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +2020/12/31 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua +2020/12/31 | 6325 | macros/luatex/generic/luaotfload/luaotfload-status.lua +2020/12/31 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty +2020/12/31 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua +2020/12/31 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua +2020/12/31 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 +2020/12/31 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua +2020/12/31 | 76773 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf +2020/12/31 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst +2020/12/31 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +2020/12/31 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua +2020/12/31 | 19847 | macros/luatex/generic/luaotfload/NEWS +2020/12/31 | 3784 | macros/luatex/generic/luaotfload/README.md +2020/12/31 | 21696 | macros/luatex/generic/luaotfload/scripts-demo.pdf +2019/12/25 | 699 | macros/luatex/generic/luaotfload/scripts-demo.tex +2020/12/31 | 8566 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf +2019/12/25 | 191 | macros/luatex/generic/luaotfload/shaper-demo-graphite.tex +2020/12/31 | 8486 | macros/luatex/generic/luaotfload/shaper-demo.pdf +2019/12/25 | 182 | macros/luatex/generic/luaotfload/shaper-demo.tex +2020/12/31 | 1927005 | macros/luatex/generic/luaotfload.zip 2019/12/22 | 2475 | macros/luatex/generic/luapackageloader/luapackageloader.lua 2019/12/22 | 33904 | macros/luatex/generic/luapackageloader/luapackageloader.pdf 2019/12/22 | 1014 | macros/luatex/generic/luapackageloader/luapackageloader.sty @@ -257703,6 +257702,8 @@ 2019/02/28 | 2944788 | systems/texlive/tlnet/archive/archaic.doc.r38005.tar.xz 2019/02/28 | 372708 | systems/texlive/tlnet/archive/archaic.r38005.tar.xz 2019/02/28 | 134456 | systems/texlive/tlnet/archive/archaic.source.r38005.tar.xz +2020/12/31 | 78944 | systems/texlive/tlnet/archive/archivo.doc.r57261.tar.xz +2020/12/31 | 319324 | systems/texlive/tlnet/archive/archivo.r57261.tar.xz 2019/02/28 | 52132 | systems/texlive/tlnet/archive/arcs.doc.r15878.tar.xz 2019/02/28 | 1516 | systems/texlive/tlnet/archive/arcs.r15878.tar.xz 2019/02/28 | 2476 | systems/texlive/tlnet/archive/arcs.source.r15878.tar.xz @@ -258436,8 +258437,8 @@ 2019/02/28 | 1088 | systems/texlive/tlnet/archive/biblatex-multiple-dm.r37081.tar.xz 2019/02/28 | 424364 | systems/texlive/tlnet/archive/biblatex-musuos.doc.r24097.tar.xz 2019/02/28 | 3796 | systems/texlive/tlnet/archive/biblatex-musuos.r24097.tar.xz -2019/02/28 | 385628 | systems/texlive/tlnet/archive/biblatex-nature.doc.r48940.tar.xz -2019/02/28 | 3272 | systems/texlive/tlnet/archive/biblatex-nature.r48940.tar.xz +2020/12/31 | 385524 | systems/texlive/tlnet/archive/biblatex-nature.doc.r57262.tar.xz +2020/12/31 | 3256 | systems/texlive/tlnet/archive/biblatex-nature.r57262.tar.xz 2019/02/28 | 156060 | systems/texlive/tlnet/archive/biblatex-nejm.doc.r49839.tar.xz 2019/02/28 | 2036 | systems/texlive/tlnet/archive/biblatex-nejm.r49839.tar.xz 2019/02/28 | 508 | systems/texlive/tlnet/archive/biblatex-nejm.source.r49839.tar.xz @@ -259399,7 +259400,7 @@ 2020/05/29 | 1224 | systems/texlive/tlnet/archive/collection-bibtexextra.r55339.tar.xz 2020/09/16 | 944 | systems/texlive/tlnet/archive/collection-binextra.r56352.tar.xz 2020/03/04 | 596 | systems/texlive/tlnet/archive/collection-context.r54074.tar.xz -2020/12/27 | 1860 | systems/texlive/tlnet/archive/collection-fontsextra.r57232.tar.xz +2020/12/31 | 1860 | systems/texlive/tlnet/archive/collection-fontsextra.r57261.tar.xz 2020/03/04 | 560 | systems/texlive/tlnet/archive/collection-fontsrecommended.r54074.tar.xz 2020/12/08 | 528 | systems/texlive/tlnet/archive/collection-fontutils.r57089.tar.xz 2020/03/04 | 568 | systems/texlive/tlnet/archive/collection-formatsextra.r54074.tar.xz @@ -259422,7 +259423,7 @@ 2020/03/04 | 408 | systems/texlive/tlnet/archive/collection-langpolish.r54074.tar.xz 2020/03/04 | 392 | systems/texlive/tlnet/archive/collection-langportuguese.r54074.tar.xz 2020/03/07 | 380 | systems/texlive/tlnet/archive/collection-langspanish.r54141.tar.xz -2020/12/29 | 6236 | systems/texlive/tlnet/archive/collection-latexextra.r57248.tar.xz +2020/12/31 | 6232 | systems/texlive/tlnet/archive/collection-latexextra.r57264.tar.xz 2020/12/03 | 696 | systems/texlive/tlnet/archive/collection-latex.r57048.tar.xz 2020/12/03 | 756 | systems/texlive/tlnet/archive/collection-latexrecommended.r57048.tar.xz 2020/12/30 | 700 | systems/texlive/tlnet/archive/collection-luatex.r57257.tar.xz @@ -262129,9 +262130,9 @@ 2020/03/24 | 1361732 | systems/texlive/tlnet/archive/gofonts.r54512.tar.xz 2019/02/28 | 9012 | systems/texlive/tlnet/archive/go.r28628.tar.xz 2019/02/28 | 416 | systems/texlive/tlnet/archive/go.source.r28628.tar.xz -2020/12/30 | 1766840 | systems/texlive/tlnet/archive/gost.doc.r57251.tar.xz -2020/12/30 | 17272 | systems/texlive/tlnet/archive/gost.r57251.tar.xz -2020/12/30 | 31956 | systems/texlive/tlnet/archive/gost.source.r57251.tar.xz +2020/12/31 | 1764668 | systems/texlive/tlnet/archive/gost.doc.r57267.tar.xz +2020/12/31 | 17456 | systems/texlive/tlnet/archive/gost.r57267.tar.xz +2020/12/31 | 32068 | systems/texlive/tlnet/archive/gost.source.r57267.tar.xz 2019/02/28 | 193528 | systems/texlive/tlnet/archive/gothic.doc.r49869.tar.xz 2019/02/28 | 129612 | systems/texlive/tlnet/archive/gothic.r49869.tar.xz 2019/02/28 | 448 | systems/texlive/tlnet/archive/gothic.source.r49869.tar.xz @@ -263998,9 +263999,9 @@ 2020/09/03 | 8576 | systems/texlive/tlnet/archive/lualibs.source.r56259.tar.xz 2020/06/08 | 226344 | systems/texlive/tlnet/archive/luamesh.doc.r55475.tar.xz 2020/06/08 | 12096 | systems/texlive/tlnet/archive/luamesh.r55475.tar.xz -2020/02/26 | 152304 | systems/texlive/tlnet/archive/luamplib.doc.r53904.tar.xz -2020/02/26 | 11692 | systems/texlive/tlnet/archive/luamplib.r53904.tar.xz -2020/02/26 | 26532 | systems/texlive/tlnet/archive/luamplib.source.r53904.tar.xz +2020/12/31 | 152328 | systems/texlive/tlnet/archive/luamplib.doc.r57266.tar.xz +2020/12/31 | 11680 | systems/texlive/tlnet/archive/luamplib.r57266.tar.xz +2020/12/31 | 26536 | systems/texlive/tlnet/archive/luamplib.source.r57266.tar.xz 2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.aarch64-linux.r46208.tar.xz 2019/02/28 | 352 | systems/texlive/tlnet/archive/luaotfload.amd64-freebsd.r34647.tar.xz 2019/02/28 | 348 | systems/texlive/tlnet/archive/luaotfload.amd64-netbsd.r34647.tar.xz @@ -265169,9 +265170,9 @@ 2019/02/28 | 3760 | systems/texlive/tlnet/archive/noitcrul.source.r15878.tar.xz 2019/02/28 | 123832 | systems/texlive/tlnet/archive/nolbreaks.doc.r26786.tar.xz 2019/02/28 | 2596 | systems/texlive/tlnet/archive/nolbreaks.r26786.tar.xz -2020/03/04 | 530908 | systems/texlive/tlnet/archive/nomencl.doc.r54080.tar.xz -2020/03/04 | 3688 | systems/texlive/tlnet/archive/nomencl.r54080.tar.xz -2020/03/04 | 18712 | systems/texlive/tlnet/archive/nomencl.source.r54080.tar.xz +2020/12/31 | 531236 | systems/texlive/tlnet/archive/nomencl.doc.r57263.tar.xz +2020/12/31 | 3776 | systems/texlive/tlnet/archive/nomencl.r57263.tar.xz +2020/12/31 | 18836 | systems/texlive/tlnet/archive/nomencl.source.r57263.tar.xz 2019/02/28 | 174560 | systems/texlive/tlnet/archive/nomentbl.doc.r16549.tar.xz 2019/02/28 | 2456 | systems/texlive/tlnet/archive/nomentbl.r16549.tar.xz 2019/02/28 | 6048 | systems/texlive/tlnet/archive/nomentbl.source.r16549.tar.xz @@ -267391,6 +267392,8 @@ 2020/11/17 | 324360 | systems/texlive/tlnet/archive/skdoc.doc.r56950.tar.xz 2020/11/17 | 9720 | systems/texlive/tlnet/archive/skdoc.r56950.tar.xz 2020/11/17 | 27656 | systems/texlive/tlnet/archive/skdoc.source.r56950.tar.xz +2020/12/31 | 220848 | systems/texlive/tlnet/archive/skeldoc.doc.r57264.tar.xz +2020/12/31 | 5764 | systems/texlive/tlnet/archive/skeldoc.r57264.tar.xz 2019/02/28 | 328064 | systems/texlive/tlnet/archive/skeycommand.doc.r24652.tar.xz 2019/02/28 | 4876 | systems/texlive/tlnet/archive/skeycommand.r24652.tar.xz 2019/02/28 | 328384 | systems/texlive/tlnet/archive/skeyval.doc.r30560.tar.xz @@ -268173,8 +268176,8 @@ 2020/03/24 | 280 | systems/texlive/tlnet/archive/texlive-cz.r54496.tar.xz 2020/12/26 | 1338744 | systems/texlive/tlnet/archive/texlive-de.doc.r57223.tar.xz 2020/12/26 | 272 | systems/texlive/tlnet/archive/texlive-de.r57223.tar.xz -2020/12/30 | 170828 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57250.tar.xz -2020/12/30 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57250.tar.xz +2020/12/31 | 170888 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57260.tar.xz +2020/12/31 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57260.tar.xz 2020/04/16 | 1891392 | systems/texlive/tlnet/archive/texlive-en.doc.r54755.tar.xz 2020/04/16 | 272 | systems/texlive/tlnet/archive/texlive-en.r54755.tar.xz 2020/03/22 | 3090144 | systems/texlive/tlnet/archive/texlive-es.doc.r54465.tar.xz @@ -269795,8 +269798,8 @@ 2019/02/28 | 3564 | systems/texlive/tlnet/archive/xtuthesis.r47049.tar.xz 2019/02/28 | 584 | systems/texlive/tlnet/archive/xunicode.doc.r30466.tar.xz 2019/02/28 | 25768 | systems/texlive/tlnet/archive/xunicode.r30466.tar.xz -2020/01/25 | 57924 | systems/texlive/tlnet/archive/xurl.doc.r53538.tar.xz -2020/01/25 | 1612 | systems/texlive/tlnet/archive/xurl.r53538.tar.xz +2020/12/31 | 58020 | systems/texlive/tlnet/archive/xurl.doc.r57265.tar.xz +2020/12/31 | 1612 | systems/texlive/tlnet/archive/xurl.r57265.tar.xz 2019/02/28 | 582912 | systems/texlive/tlnet/archive/xwatermark.doc.r28090.tar.xz 2019/02/28 | 16524 | systems/texlive/tlnet/archive/xwatermark.r28090.tar.xz 2019/02/28 | 148332 | systems/texlive/tlnet/archive/xyling.doc.r15878.tar.xz @@ -269916,16 +269919,16 @@ 2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz 2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz 2020/12/03 | 105972 | systems/texlive/tlnet/install-tl -2020/12/30 | 5500415 | systems/texlive/tlnet/install-tl-unx.tar.gz -2020/12/30 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 -2020/12/30 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2020/12/31 | 5500969 | systems/texlive/tlnet/install-tl-unx.tar.gz +2020/12/31 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2020/12/31 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc 2020/08/23 | 4889 | systems/texlive/tlnet/install-tl-windows.bat -2020/12/30 | 19387534 | systems/texlive/tlnet/install-tl-windows.exe -2020/12/30 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 -2020/12/30 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2020/12/30 | 24270384 | systems/texlive/tlnet/install-tl.zip -2020/12/30 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 -2020/12/30 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2020/12/31 | 19387619 | systems/texlive/tlnet/install-tl-windows.exe +2020/12/31 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2020/12/31 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2020/12/31 | 24270384 | systems/texlive/tlnet/install-tl.zip +2020/12/31 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2020/12/31 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc 2020/03/05 | 1215 | systems/texlive/tlnet/README.md 2020/04/06 | 5961 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg 2016/04/12 | 600 | systems/texlive/tlnet/tlpkg/gpg/random_seed @@ -269981,12 +269984,12 @@ 2020/05/17 | 20322 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm 2020/05/03 | 4786 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm 2020/09/22 | 27563 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm -2020/12/30 | 16783174 | systems/texlive/tlnet/tlpkg/texlive.tlpdb -2020/12/30 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2020/12/31 | 16810760 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2020/12/31 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 2020/05/13 | 86417 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm -2020/12/30 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 -2020/12/30 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2020/12/30 | 2257520 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2020/12/31 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2020/12/31 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2020/12/31 | 2257956 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz 2020/04/15 | 58761 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm 2020/03/20 | 41736 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm 2020/05/11 | 15010 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm @@ -274554,7 +274557,7 @@ 2020/10/03 | 318630 | systems/win32/miktex/tm/packages/filehook.tar.lzma 2012/12/04 | 924573 | systems/win32/miktex/tm/packages/fileinfo.tar.lzma 2011/09/21 | 281409 | systems/win32/miktex/tm/packages/filemod.tar.lzma -2020/12/30 | 554529 | systems/win32/miktex/tm/packages/files.csv.lzma +2020/12/31 | 554529 | systems/win32/miktex/tm/packages/files.csv.lzma 2001/05/14 | 5617 | systems/win32/miktex/tm/packages/finbib.tar.lzma 2015/10/20 | 44379 | systems/win32/miktex/tm/packages/findhyph.tar.lzma 2011/10/21 | 89323 | systems/win32/miktex/tm/packages/fink.tar.lzma @@ -275733,9 +275736,9 @@ 2018/01/12 | 157226 | systems/win32/miktex/tm/packages/miktex-zip-bin-x64.tar.lzma 2020/12/14 | 39268 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma 2020/12/14 | 43043 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma -2020/12/30 | 205354 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma -2020/12/30 | 1233774 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma -2020/12/30 | 1151438 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma +2020/12/31 | 205396 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma +2020/12/31 | 1233537 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma +2020/12/31 | 1150826 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma 2020/12/14 | 13302 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma 2020/12/14 | 14143 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma 2016/07/15 | 35914 | systems/win32/miktex/tm/packages/mil3.tar.lzma @@ -275892,187 +275895,187 @@ 2018/04/09 | 400132 | systems/win32/miktex/tm/packages/newunicodechar.tar.lzma 2011/09/19 | 101312 | systems/win32/miktex/tm/packages/newvbtm.tar.lzma 2020/09/06 | 231669 | systems/win32/miktex/tm/packages/newverbs.tar.lzma -2020/12/30 | 554006 | systems/win32/miktex/tm/packages/next/files.csv.lzma -2020/12/30 | 50709 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma -2020/12/30 | 56363 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma -2020/12/30 | 967930 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma -2020/12/30 | 1078478 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma -2020/12/30 | 28978 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma -2020/12/30 | 31349 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma -2020/12/30 | 29410 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma -2020/12/30 | 34194 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma -2020/12/30 | 50032 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma -2020/12/30 | 57436 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma -2020/12/30 | 85011 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma -2020/12/30 | 94552 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma -2020/12/30 | 65803 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma -2020/12/30 | 73674 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma -2020/12/30 | 27198 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma -2020/12/30 | 30889 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma -2020/12/30 | 330225 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma -2020/12/30 | 392500 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma -2020/12/30 | 32597 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma -2020/12/30 | 36596 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma -2020/12/30 | 51320 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma -2020/12/30 | 56471 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma -2020/12/30 | 212397 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma -2020/12/30 | 231839 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma -2020/12/30 | 179341 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma -2020/12/30 | 195611 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma -2020/12/30 | 52165 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma -2020/12/30 | 59081 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma -2020/12/30 | 21166 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma -2020/12/30 | 23265 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma -2020/12/30 | 460885 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma -2020/12/30 | 45541 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma -2020/12/30 | 51381 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma -2020/12/30 | 280109 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma -2020/12/30 | 319753 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma -2020/12/30 | 41009 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma -2020/12/30 | 45199 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma -2020/12/30 | 116824 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma -2020/12/30 | 131229 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma -2020/12/30 | 1282238 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma -2020/12/30 | 1416387 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma -2020/12/30 | 87596 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma -2020/12/30 | 99427 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma -2020/12/30 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma -2020/12/30 | 47850 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma -2020/12/30 | 25090 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma -2020/12/30 | 27947 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma -2020/12/30 | 55790 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma -2020/12/30 | 62814 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma -2020/12/30 | 134712 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma -2020/12/30 | 152375 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma -2020/12/30 | 73242 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma -2020/12/30 | 77820 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma -2020/12/30 | 71568 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma -2020/12/30 | 80621 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma -2020/12/30 | 258691 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma -2020/12/30 | 295531 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma -2020/12/30 | 22020 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma -2020/12/30 | 25015 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma -2020/12/30 | 99662 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma -2020/12/30 | 114807 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma -2020/12/30 | 63801 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma -2020/12/30 | 72839 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma -2020/12/30 | 94662 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma -2020/12/30 | 113773 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma -2020/12/30 | 38038 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma -2020/12/30 | 42572 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma -2020/12/30 | 483101 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma -2020/12/30 | 567838 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma -2020/12/30 | 147334 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma -2020/12/30 | 159925 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma -2020/12/30 | 94834 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma -2020/12/30 | 109178 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma -2020/12/30 | 16216 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma -2020/12/30 | 17876 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma -2020/12/30 | 28229 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma -2020/12/30 | 29931 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma -2020/12/30 | 624740 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma -2020/12/30 | 680036 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma -2020/12/30 | 531711 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma -2020/12/30 | 594930 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma -2020/12/30 | 475839 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma -2020/12/30 | 511888 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma -2020/12/30 | 94180 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma -2020/12/30 | 103387 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma -2020/12/30 | 1699737 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma -2020/12/30 | 1985831 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma -2020/12/30 | 67664 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma -2020/12/30 | 74153 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma -2020/12/30 | 27195 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma -2020/12/30 | 31392 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma -2020/12/30 | 7751 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma -2020/12/30 | 8783 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma -2020/12/30 | 194178 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma -2020/12/30 | 212474 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma -2020/12/30 | 250138 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma -2020/12/30 | 283901 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma -2020/12/30 | 96815 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma -2020/12/30 | 101755 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma -2020/12/30 | 60504 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma -2020/12/30 | 67766 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma -2020/12/30 | 120281 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma -2020/12/30 | 131918 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma -2020/12/30 | 145309 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma -2020/12/30 | 162262 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma -2020/12/30 | 199606 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma -2020/12/30 | 180253 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma -2020/12/30 | 67634 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma -2020/12/30 | 77796 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma -2020/12/30 | 31249 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma -2020/12/30 | 35038 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma -2020/12/30 | 36703 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma -2020/12/30 | 41319 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma -2020/12/30 | 42942 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma -2020/12/30 | 46877 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma -2020/12/30 | 45843 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma -2020/12/30 | 52462 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma -2020/12/30 | 193530 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma -2020/12/30 | 210605 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma -2020/12/30 | 35470 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma -2020/12/30 | 39566 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma -2020/12/30 | 744396 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma -2020/12/30 | 809095 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma -2020/12/30 | 198078 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma -2020/12/30 | 202753 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma -2020/12/30 | 207981 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma -2020/12/30 | 243464 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma -2020/12/30 | 78764 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma -2020/12/30 | 87882 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma -2020/12/30 | 1171089 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma -2020/12/30 | 1304654 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma -2020/12/30 | 20132 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma -2020/12/30 | 23866 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma -2020/12/30 | 31551 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma -2020/12/30 | 37233 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma -2020/12/30 | 63846 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma -2020/12/30 | 71935 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma -2020/12/30 | 43151 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma -2020/12/30 | 51768 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma -2020/12/30 | 1253449 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma -2020/12/30 | 1380784 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma -2020/12/30 | 42287 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma -2020/12/30 | 51746 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma -2020/12/30 | 56208 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma -2020/12/30 | 59673 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma -2020/12/30 | 27041 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma -2020/12/30 | 29264 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma -2020/12/30 | 16233 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma -2020/12/30 | 18009 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma -2020/12/30 | 63560 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma -2020/12/30 | 70011 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma -2020/12/30 | 152157 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma -2020/12/30 | 165760 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma -2020/12/30 | 57101 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma -2020/12/30 | 65470 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma -2020/12/30 | 98044 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma -2020/12/30 | 104831 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma -2020/12/30 | 2495179 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma -2020/12/30 | 2616450 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma -2020/12/30 | 55136 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma -2020/12/30 | 61949 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma -2020/12/30 | 33387 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma -2020/12/30 | 37233 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma -2020/12/30 | 27212 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma -2020/12/30 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma -2020/12/30 | 66264 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma -2020/12/30 | 70292 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma -2020/12/30 | 309294 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma -2020/12/30 | 343640 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma -2020/12/30 | 582486 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma -2020/12/30 | 618635 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma -2020/12/30 | 39542 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma -2020/12/30 | 43398 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma -2020/12/30 | 205396 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma -2020/12/30 | 1233455 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma -2020/12/30 | 1151428 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma -2020/12/30 | 13475 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma -2020/12/30 | 14358 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma +2020/12/31 | 554006 | systems/win32/miktex/tm/packages/next/files.csv.lzma +2020/12/31 | 50711 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma +2020/12/31 | 56365 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma +2020/12/31 | 967932 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma +2020/12/31 | 1078478 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma +2020/12/31 | 28976 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma +2020/12/31 | 31350 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma +2020/12/31 | 29410 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma +2020/12/31 | 34195 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma +2020/12/31 | 50033 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma +2020/12/31 | 57438 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma +2020/12/31 | 85012 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma +2020/12/31 | 94552 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma +2020/12/31 | 65803 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma +2020/12/31 | 73674 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma +2020/12/31 | 27199 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma +2020/12/31 | 30890 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma +2020/12/31 | 330226 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma +2020/12/31 | 392499 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma +2020/12/31 | 32598 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma +2020/12/31 | 36597 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma +2020/12/31 | 51321 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma +2020/12/31 | 56472 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma +2020/12/31 | 212400 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma +2020/12/31 | 231839 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma +2020/12/31 | 179341 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma +2020/12/31 | 195612 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma +2020/12/31 | 52164 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma +2020/12/31 | 59081 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma +2020/12/31 | 21167 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma +2020/12/31 | 23265 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma +2020/12/31 | 460885 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma +2020/12/31 | 45543 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma +2020/12/31 | 51383 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma +2020/12/31 | 280109 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma +2020/12/31 | 319754 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma +2020/12/31 | 41011 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma +2020/12/31 | 45200 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma +2020/12/31 | 116823 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma +2020/12/31 | 131230 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma +2020/12/31 | 1282239 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma +2020/12/31 | 1416387 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma +2020/12/31 | 87597 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma +2020/12/31 | 99427 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma +2020/12/31 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma +2020/12/31 | 47850 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma +2020/12/31 | 25091 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma +2020/12/31 | 27946 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma +2020/12/31 | 55790 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma +2020/12/31 | 62811 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma +2020/12/31 | 134710 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma +2020/12/31 | 152375 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma +2020/12/31 | 73241 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma +2020/12/31 | 77819 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma +2020/12/31 | 71566 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma +2020/12/31 | 80621 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma +2020/12/31 | 258692 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma +2020/12/31 | 295529 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma +2020/12/31 | 22019 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma +2020/12/31 | 25014 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma +2020/12/31 | 99662 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma +2020/12/31 | 114806 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma +2020/12/31 | 63802 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma +2020/12/31 | 72838 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma +2020/12/31 | 94661 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma +2020/12/31 | 113771 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma +2020/12/31 | 38038 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma +2020/12/31 | 42572 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma +2020/12/31 | 483100 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma +2020/12/31 | 567837 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma +2020/12/31 | 147333 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma +2020/12/31 | 159922 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma +2020/12/31 | 94833 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma +2020/12/31 | 109176 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma +2020/12/31 | 16216 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma +2020/12/31 | 17875 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma +2020/12/31 | 28228 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma +2020/12/31 | 29931 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma +2020/12/31 | 624742 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma +2020/12/31 | 680034 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma +2020/12/31 | 531712 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma +2020/12/31 | 594930 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma +2020/12/31 | 475842 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma +2020/12/31 | 511891 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma +2020/12/31 | 94179 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma +2020/12/31 | 103388 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma +2020/12/31 | 1699739 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma +2020/12/31 | 1985832 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma +2020/12/31 | 67663 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma +2020/12/31 | 74152 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma +2020/12/31 | 27194 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma +2020/12/31 | 31390 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma +2020/12/31 | 7753 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma +2020/12/31 | 8786 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma +2020/12/31 | 194176 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma +2020/12/31 | 212473 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma +2020/12/31 | 250140 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma +2020/12/31 | 283901 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma +2020/12/31 | 96816 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma +2020/12/31 | 101757 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma +2020/12/31 | 60505 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma +2020/12/31 | 67765 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma +2020/12/31 | 120284 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma +2020/12/31 | 131918 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma +2020/12/31 | 145308 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma +2020/12/31 | 162264 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma +2020/12/31 | 199606 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma +2020/12/31 | 180252 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma +2020/12/31 | 67634 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma +2020/12/31 | 77796 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma +2020/12/31 | 31247 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma +2020/12/31 | 35039 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma +2020/12/31 | 36703 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma +2020/12/31 | 41319 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma +2020/12/31 | 42941 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma +2020/12/31 | 46876 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma +2020/12/31 | 45842 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma +2020/12/31 | 52461 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma +2020/12/31 | 193531 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma +2020/12/31 | 210603 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma +2020/12/31 | 35469 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma +2020/12/31 | 39565 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma +2020/12/31 | 744396 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma +2020/12/31 | 809095 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma +2020/12/31 | 198077 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma +2020/12/31 | 202753 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma +2020/12/31 | 207981 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma +2020/12/31 | 243464 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma +2020/12/31 | 78765 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma +2020/12/31 | 87881 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma +2020/12/31 | 1171086 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma +2020/12/31 | 1304654 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma +2020/12/31 | 20132 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma +2020/12/31 | 23866 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma +2020/12/31 | 31553 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma +2020/12/31 | 37230 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma +2020/12/31 | 63847 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma +2020/12/31 | 71936 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma +2020/12/31 | 43151 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma +2020/12/31 | 51767 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma +2020/12/31 | 1253450 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma +2020/12/31 | 1380782 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma +2020/12/31 | 42288 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma +2020/12/31 | 51746 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma +2020/12/31 | 56208 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma +2020/12/31 | 59674 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma +2020/12/31 | 27042 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma +2020/12/31 | 29263 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma +2020/12/31 | 16234 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma +2020/12/31 | 18009 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma +2020/12/31 | 63561 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma +2020/12/31 | 70011 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma +2020/12/31 | 152156 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma +2020/12/31 | 165760 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma +2020/12/31 | 57100 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma +2020/12/31 | 65469 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma +2020/12/31 | 98045 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma +2020/12/31 | 104832 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma +2020/12/31 | 2495180 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma +2020/12/31 | 2616450 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma +2020/12/31 | 55139 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma +2020/12/31 | 61948 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma +2020/12/31 | 33387 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma +2020/12/31 | 37232 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma +2020/12/31 | 27212 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma +2020/12/31 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma +2020/12/31 | 66264 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma +2020/12/31 | 70292 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma +2020/12/31 | 309293 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma +2020/12/31 | 343641 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma +2020/12/31 | 582487 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma +2020/12/31 | 618637 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma +2020/12/31 | 39540 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma +2020/12/31 | 43398 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma +2020/12/31 | 205351 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma +2020/12/31 | 1233294 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma +2020/12/31 | 1151165 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma +2020/12/31 | 13476 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma +2020/12/31 | 14356 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma 2019/03/12 | 1412 | systems/win32/miktex/tm/packages/nextpage.tar.lzma -2020/12/30 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini +2020/12/31 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini 2018/07/06 | 145915 | systems/win32/miktex/tm/packages/nexus-otf.tar.lzma 2017/03/30 | 191149 | systems/win32/miktex/tm/packages/nfssext-cfr.tar.lzma 2012/12/20 | 612251 | systems/win32/miktex/tm/packages/nicefilelist.tar.lzma @@ -276398,7 +276401,7 @@ 2020/10/20 | 342254 | systems/win32/miktex/tm/packages/preview.tar.lzma 2019/06/20 | 375963 | systems/win32/miktex/tm/packages/prftree.tar.lzma 2020/10/27 | 357822 | systems/win32/miktex/tm/packages/principia.tar.lzma -2020/12/30 | 835 | systems/win32/miktex/tm/packages/pr.ini +2020/12/31 | 835 | systems/win32/miktex/tm/packages/pr.ini 2010/09/27 | 248469 | systems/win32/miktex/tm/packages/printlen.tar.lzma 2008/06/17 | 77313 | systems/win32/miktex/tm/packages/proba.tar.lzma 2017/07/12 | 988486 | systems/win32/miktex/tm/packages/probsoln.tar.lzma @@ -277565,9 +277568,9 @@ 2019/08/12 | 14654 | systems/win32/w32tex/00FILES.euc 2019/08/12 | 14654 | systems/win32/w32tex/00FILES.sjis 2020/12/17 | 5176928 | systems/win32/w32tex/aleph-w32.tar.xz -2020/11/16 | 65991060 | systems/win32/w32tex/biblatex-biber.tar.xz +2020/12/30 | 65991924 | systems/win32/w32tex/biblatex-biber.tar.xz 2016/12/13 | 65971452 | systems/win32/w32tex/cbfonts.tar.xz -2020/12/29 | 759079 | systems/win32/w32tex/ChangeLog +2020/12/30 | 759306 | systems/win32/w32tex/ChangeLog 2009/08/03 | 141221 | systems/win32/w32tex/ChangeLog.0 2009/08/03 | 221890 | systems/win32/w32tex/ChangeLog.1 2009/08/03 | 116462 | systems/win32/w32tex/ChangeLog.2 @@ -277610,7 +277613,7 @@ 2020/12/05 | 1245344 | systems/win32/w32tex/omegaj-w32.tar.xz 2020/11/16 | 324540 | systems/win32/w32tex/otfbeta.tar.xz 2020/12/08 | 21137904 | systems/win32/w32tex/pdftex-w32.tar.xz -2020/12/29 | 87572488 | systems/win32/w32tex/pgfcontrib.tar.xz +2020/12/30 | 87576132 | systems/win32/w32tex/pgfcontrib.tar.xz 2015/01/26 | 189072 | systems/win32/w32tex/plain2-2.54-w32.tar.xz 2020/11/27 | 2807432 | systems/win32/w32tex/platex.tar.xz 2020/03/20 | 1598792 | systems/win32/w32tex/pmx.tar.xz @@ -277618,7 +277621,7 @@ 2020/10/25 | 274208000 | systems/win32/w32tex/pstricks.tar.xz 2020/12/05 | 517812 | systems/win32/w32tex/psutils-w32.tar.xz 2020/12/17 | 6608484 | systems/win32/w32tex/ptex-ng-w32.tar.xz -2020/12/17 | 10585120 | systems/win32/w32tex/ptex-w32.tar.xz +2020/12/30 | 10588256 | systems/win32/w32tex/ptex-w32.tar.xz 2019/04/15 | 499188 | systems/win32/w32tex/sam2p-w32.tar.xz 2020/10/14 | 87958692 | systems/win32/w32tex/t1fonts.tar.xz 2020/10/31 | 142032 | systems/win32/w32tex/t1utils-w32.tar.xz @@ -277787,7 +277790,7 @@ 2004/06/04 | 404 | tds/tds.sed 2004/06/23 | 65418 | tds/tds.tex 2019/05/29 | 304264 | tds.zip -2020/12/31 | 186 | timestamp +2021/01/01 | 186 | timestamp 2002/08/26 | 61898 | usergrps/dante/antrag.pdf 2002/08/26 | 118217 | usergrps/dante/antrag.ps 2017/06/30 | 917 | usergrps/dante/dtk/doc/beispiel.bib diff --git a/FILES.byname.gz b/FILES.byname.gz index c4ceb7de6e..032434354d 100644 Binary files a/FILES.byname.gz and b/FILES.byname.gz differ diff --git a/FILES.last07days b/FILES.last07days index e1869a8977..4519ba4b73 100644 --- a/FILES.last07days +++ b/FILES.last07days @@ -1,44 +1,864 @@ -2020/12/30 | 99662 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma -2020/12/30 | 99427 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma -2020/12/30 | 98044 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma -2020/12/30 | 96815 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma -2020/12/30 | 967930 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma -2020/12/30 | 94834 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma -2020/12/30 | 94662 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma -2020/12/30 | 94552 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma -2020/12/30 | 94180 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma +2020/12/31 | 99 | macros/latex/contrib/biblatex/latex/bbx/authoryear-icomp.bbx +2020/12/31 | 99662 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma +2020/12/31 | 99427 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-ibid.bbx +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/authoryear-comp.bbx +2020/12/31 | 98 | macros/latex/contrib/biblatex/latex/bbx/alphabetic-verb.bbx +2020/12/31 | 989398 | macros/latex/base/ltnews.pdf +2020/12/31 | 98669 | macros/luatex/generic/luaotfload/luaotfload-main.tex +2020/12/31 | 9853 | macros/latex/contrib/biblatex/latex/cbx/authoryear-icomp.cbx +2020/12/31 | 98442 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-biber.pdf +2020/12/31 | 98437 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment-bibtex.pdf +2020/12/31 | 98395 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-biber.pdf +2020/12/31 | 98390 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section-bibtex.pdf +2020/12/31 | 9810 | macros/latex/base/ltnews21.tex +2020/12/31 | 98045 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad3.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad2.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-trad1.bbx +2020/12/31 | 97 | macros/latex/contrib/biblatex/latex/bbx/verbose-inote.bbx +2020/12/31 | 9725 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2.tex +2020/12/31 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-note.bbx +2020/12/31 | 96 | macros/latex/contrib/biblatex/latex/bbx/verbose-ibid.bbx +2020/12/31 | 96816 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma +2020/12/31 | 967932 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma +2020/12/31 | 964020 | macros/luatex/generic/luaotfload/fontloader-reference.lua +2020/12/31 | 9620 | macros/latex/contrib/biblatex/latex/cbx/verbose-inote.cbx +2020/12/31 | 9562 | macros/latex/base/ltcntrl.dtx +2020/12/31 | 94833 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma +2020/12/31 | 94661 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma +2020/12/31 | 9460 | macros/latex/base/format.ins +2020/12/31 | 94552 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma +2020/12/31 | 94470 | macros/luatex/generic/luaotfload/fontloader-font-otr.lua +2020/12/31 | 94179 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma +2020/12/31 | 9401 | macros/latex/base/syntonly.dtx +2020/12/31 | 9374 | macros/latex/base/preload.dtx +2020/12/31 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-verb.bbx +2020/12/31 | 92 | macros/latex/contrib/biblatex/latex/bbx/numeric-comp.bbx +2020/12/31 | 926391 | macros/latex/base/lthooks-code.pdf +2020/12/31 | 91 | macros/latex/contrib/biblatex/latex/bbx/verbose.bbx +2020/12/31 | 91946 | macros/latex/contrib/biblatex/latex/biblatex.def +2020/12/31 | 9091 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad1.cbx +2020/12/31 | 90768 | macros/latex/base/fntguide.tex +2020/12/31 | 9068 | macros/latex/base/lppl-1-0.txt +2020/12/31 | 89720 | macros/latex/base/slides.dtx +2020/12/31 | 89678 | macros/luatex/generic/luaotfload/fontloader-font-cff.lua +2020/12/31 | 89386 | macros/latex/base/utf8ienc.dtx +2020/12/31 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-bibtex.pdf +2020/12/31 | 88905 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry-biber.pdf +2020/12/31 | 8864 | macros/latex/base/ltnews17.tex +2020/12/31 | 88411 | macros/latex/base/lttextcomp.dtx +2020/12/31 | 8840 | macros/luatex/generic/luaotfload/luaotfload-loaders.lua +2020/12/31 | 87 | macros/latex/contrib/biblatex/latex/cbx/reading.cbx +2020/12/31 | 87881 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma +2020/12/31 | 8786 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma +2020/12/31 | 8784 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad2.cbx +2020/12/31 | 87597 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma +2020/12/31 | 8737 | macros/latex/contrib/biblatex/latex/cbx/authoryear-comp.cbx +2020/12/31 | 8737 | macros/latex/base/ltthm.dtx +2020/12/31 | 8688 | macros/latex/contrib/biblatex/latex/cbx/verbose-note.cbx +2020/12/31 | 8632 | macros/latex/base/oldlfont.dtx +2020/12/31 | 863103 | macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua +2020/12/31 | 8597 | macros/luatex/generic/luaotfload/filegraph.tex +2020/12/31 | 85744 | macros/latex/base/ltdefns.dtx +2020/12/31 | 856 | macros/latex/contrib/biblatex/latex/lbx/newzealand.lbx +2020/12/31 | 8566 | macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf +2020/12/31 | 85012 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma +2020/12/31 | 8493 | macros/latex/base/texpert.txt +2020/12/31 | 8486 | macros/luatex/generic/luaotfload/shaper-demo.pdf +2020/12/31 | 8433 | macros/latex/contrib/biblatex/latex/blx-case-expl3.sty +2020/12/31 | 840 | macros/latex/contrib/biblatex/doc/examples/82-style-debug.tex +2020/12/31 | 8363 | macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty +2020/12/31 | 835 | systems/win32/miktex/tm/packages/pr.ini +2020/12/31 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-bibtex.pdf +2020/12/31 | 81705 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section-biber.pdf +2020/12/31 | 81487 | macros/luatex/generic/lualibs/lualibs.pdf +2020/12/31 | 8115 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3.tex +2020/12/31 | 810 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes.tex +2020/12/31 | 8100 | macros/latex/base/ltnews.tex +2020/12/31 | 809095 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma +2020/12/31 | 80621 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma +2020/12/31 | 8029 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote.tex +2020/12/31 | 8024 | macros/latex/contrib/biblatex/latex/bbx/authoryear.bbx +2020/12/31 | 80156 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-biber.pdf +2020/12/31 | 80152 | macros/latex/contrib/biblatex/doc/examples/04-delimiters-bibtex.pdf +2020/12/31 | 79873 | macros/latex/base/ltfssbas.dtx +2020/12/31 | 7936 | macros/latex/contrib/biblatex/latex/cbx/verbose-trad3.cbx +2020/12/31 | 791 | macros/latex/contrib/biblatex/doc/examples/81-style-draft.tex +2020/12/31 | 78944 | systems/texlive/tlnet/archive/archivo.doc.r57261.tar.xz +2020/12/31 | 78765 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma +2020/12/31 | 783 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type.tex +2020/12/31 | 782 | macros/latex/contrib/biblatex/latex/lbx/australian.lbx +2020/12/31 | 7801 | macros/latex/contrib/biblatex/latex/cbx/verbose-ibid.cbx +2020/12/31 | 77819 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma +2020/12/31 | 77796 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma +2020/12/31 | 7753 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma +2020/12/31 | 7750 | macros/latex/contrib/biblatex/doc/examples/96-dates.tex +2020/12/31 | 77331 | macros/luatex/generic/luaotfload/luaotfload-conf.pdf +2020/12/31 | 7710 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear.tex +2020/12/31 | 769 | macros/latex/contrib/biblatex/latex/lbx/nswissgerman.lbx +2020/12/31 | 76773 | macros/luatex/generic/luaotfload/luaotfload-tool.pdf +2020/12/31 | 7627 | macros/latex/base/source2edoc.cls +2020/12/31 | 7589 | macros/luatex/generic/luaotfload/luaotfload-unicode.lua +2020/12/31 | 757 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template.tex +2020/12/31 | 7528 | macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +2020/12/31 | 7526 | macros/latex/base/ltxguide.cls +2020/12/31 | 750748 | macros/latex/base/ltshipout-code.pdf +2020/12/31 | 7478 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid.tex +2020/12/31 | 744 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb.tex +2020/12/31 | 744396 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma +2020/12/31 | 744388 | macros/latex/base/ltfilehook-code.pdf +2020/12/31 | 74152 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma +2020/12/31 | 74092 | macros/latex/base/ltfssini.dtx +2020/12/31 | 73674 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma +2020/12/31 | 7326 | macros/latex/base/ltnews20.tex +2020/12/31 | 73241 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma +2020/12/31 | 7288 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp.tex +2020/12/31 | 72838 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma +2020/12/31 | 7222 | macros/latex/base/exscale.dtx +2020/12/31 | 7200 | macros/latex/base/sample2e.tex +2020/12/31 | 71936 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma +2020/12/31 | 71566 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma +2020/12/31 | 70292 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma +2020/12/31 | 7002 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid.tex +2020/12/31 | 70011 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma +2020/12/31 | 7000 | macros/latex/contrib/biblatex/latex/cbx/verbose.cbx +2020/12/31 | 69 | macros/latex/contrib/biblatex/latex/biblatex.cfg +2020/12/31 | 69051 | macros/latex/base/clsguide.tex +2020/12/31 | 68914 | macros/latex/base/ltpictur.dtx +2020/12/31 | 6872 | macros/latex/base/ltnews13.tex +2020/12/31 | 68428 | macros/latex/base/usrguide.tex +2020/12/31 | 6809 | macros/luatex/generic/luaotfload/luaotfload-case.lua +2020/12/31 | 68013 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bib +2020/12/31 | 68013 | macros/latex/contrib/biblatex/bibtex/bib/biblatex/biblatex-examples.bib +2020/12/31 | 680034 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma +2020/12/31 | 67765 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma +2020/12/31 | 67663 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma +2020/12/31 | 6764 | macros/latex/base/slides.ins +2020/12/31 | 67634 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma +2020/12/31 | 67333 | macros/latex/base/ltfsstrc.dtx +2020/12/31 | 6715 | macros/latex/base/latexsym.dtx +2020/12/31 | 6654 | macros/latex/base/alltt.dtx +2020/12/31 | 6648 | macros/latex/contrib/biblatex/latex/cbx/authortitle-icomp.cbx +2020/12/31 | 66264 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma +2020/12/31 | 65803 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma +2020/12/31 | 65656 | macros/luatex/generic/luaotfload/fontloader-font-otj.lua +2020/12/31 | 65469 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma +2020/12/31 | 65407 | macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst +2020/12/31 | 64482 | macros/latex/base/ltluatex.dtx +2020/12/31 | 6405 | macros/luatex/generic/luaotfload/fontloader-l-lua.lua +2020/12/31 | 63847 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma +2020/12/31 | 63802 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma +2020/12/31 | 6363 | macros/latex/base/newlfont.dtx +2020/12/31 | 63561 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma +2020/12/31 | 63376 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists-biber.pdf +2020/12/31 | 6325 | macros/luatex/generic/luaotfload/luaotfload-status.lua +2020/12/31 | 631201 | macros/latex/base/doc.pdf +2020/12/31 | 63054 | macros/luatex/generic/luaotfload/fontloader-font-con.lua +2020/12/31 | 62811 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma +2020/12/31 | 6274 | macros/latex/base/ltnews14.tex +2020/12/31 | 626854 | macros/latex/base/lthooks-doc.pdf +2020/12/31 | 6259 | macros/luatex/generic/luaotfload/luaotfload-szss.lua +2020/12/31 | 624742 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma +2020/12/31 | 62436 | macros/latex/base/letter.dtx +2020/12/31 | 6232 | systems/texlive/tlnet/archive/collection-latexextra.r57264.tar.xz +2020/12/31 | 61948 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma +2020/12/31 | 618637 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma +2020/12/31 | 61441 | macros/latex/base/ltshipout.dtx +2020/12/31 | 61221 | macros/latex/base/ltfssdcl.dtx +2020/12/31 | 60505 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma +2020/12/31 | 60334 | macros/latex/base/fontdef.dtx +2020/12/31 | 59674 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma +2020/12/31 | 59498 | macros/latex/base/ltfilehook.dtx +2020/12/31 | 594930 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma +2020/12/31 | 59344 | macros/luatex/generic/luaotfload/fontloader-font-ttf.lua +2020/12/31 | 59081 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma +2020/12/31 | 5888 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note.tex +2020/12/31 | 5865 | macros/latex/base/ltidxglo.dtx +2020/12/31 | 5854 | macros/latex/base/ltpar.dtx +2020/12/31 | 5840 | macros/latex/base/ltnews15.tex +2020/12/31 | 582487 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma +2020/12/31 | 58020 | systems/texlive/tlnet/archive/xurl.doc.r57265.tar.xz +2020/12/31 | 5780 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp.tex +2020/12/31 | 5777 | macros/latex/base/ltnews16.tex +2020/12/31 | 5764 | systems/texlive/tlnet/archive/skeldoc.r57264.tar.xz +2020/12/31 | 57438 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma +2020/12/31 | 5725 | macros/latex/base/latexrelease.ins +2020/12/31 | 57209 | macros/latex/base/ltmiscen.dtx +2020/12/31 | 571 | macros/latex/contrib/biblatex/latex/lbx/naustrian.lbx +2020/12/31 | 5716 | macros/latex/base/inputenc.ins +2020/12/31 | 57100 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma +2020/12/31 | 5696 | macros/latex/base/ltnews08.tex +2020/12/31 | 567837 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma +2020/12/31 | 5661 | macros/latex/contrib/biblatex/latex/cbx/authortitle-comp.cbx +2020/12/31 | 5660 | macros/latex/base/ltnews10.tex +2020/12/31 | 56472 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma +2020/12/31 | 56365 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma +2020/12/31 | 56208 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma +2020/12/31 | 5609 | macros/latex/base/ltnews05.tex +2020/12/31 | 55790 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma +2020/12/31 | 554529 | systems/win32/miktex/tm/packages/files.csv.lzma +2020/12/31 | 554006 | systems/win32/miktex/tm/packages/next/files.csv.lzma +2020/12/31 | 5530 | macros/latex/base/ltnews11.tex +2020/12/31 | 5515 | macros/latex/base/graphpap.dtx +2020/12/31 | 55139 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma +2020/12/31 | 5507 | macros/latex/base/ltnews27.tex +2020/12/31 | 5507 | macros/latex/base/ltnews04.tex +2020/12/31 | 5500969 | systems/texlive/tlnet/install-tl-unx.tar.gz +2020/12/31 | 5474 | macros/latex/base/ltnews25.tex +2020/12/31 | 545 | macros/latex/contrib/biblatex/doc/examples/02-annotations.tex +2020/12/31 | 5426 | macros/latex/base/ltnews07.tex +2020/12/31 | 5418 | macros/latex/base/ltnews12.tex +2020/12/31 | 5391 | macros/latex/base/ltnews06.tex +2020/12/31 | 531712 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma +2020/12/31 | 531236 | systems/texlive/tlnet/archive/nomencl.doc.r57263.tar.xz +2020/12/31 | 5294 | macros/latex/base/ltnews09.tex +2020/12/31 | 5284 | macros/latex/base/ltnews02.tex +2020/12/31 | 52814 | macros/latex/base/encguide.tex +2020/12/31 | 5275 | macros/latex/base/cmextra.ins +2020/12/31 | 52648 | macros/latex/base/ltfiles.dtx +2020/12/31 | 52532 | macros/latex/base/lb2.err +2020/12/31 | 52461 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma +2020/12/31 | 5239 | macros/latex/base/ltnews01.tex +2020/12/31 | 52203 | macros/luatex/generic/luaotfload/luaotfload-tool.lua +2020/12/31 | 52164 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma +2020/12/31 | 520 | macros/latex/contrib/biblatex/latex/lbx/ngerman.lbx +2020/12/31 | 520923 | macros/latex/base/ltnews32.pdf +2020/12/31 | 520851 | macros/latex/base/classes.pdf +2020/12/31 | 5201 | macros/latex/base/ltnews03.tex +2020/12/31 | 5197 | macros/latex/contrib/biblatex/README +2020/12/31 | 51767 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma +2020/12/31 | 5175 | macros/latex/contrib/biblatex/doc/examples/01-introduction.tex +2020/12/31 | 51746 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma +2020/12/31 | 516587 | macros/latex/base/ltfilehook-doc.pdf +2020/12/31 | 51383 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma +2020/12/31 | 51321 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma +2020/12/31 | 5131 | macros/latex/contrib/biblatex/latex/cbx/authoryear-ibid.cbx +2020/12/31 | 51314 | macros/latex/base/ltfloat.dtx +2020/12/31 | 511891 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma +2020/12/31 | 5091 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple.tex +2020/12/31 | 50711 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma +2020/12/31 | 506356 | macros/latex/contrib/biblatex/latex/biblatex.sty +2020/12/31 | 505 | macros/latex/contrib/biblatex/doc/examples/95-customlists.bib +2020/12/31 | 5047 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose.tex +2020/12/31 | 5044 | macros/latex/base/latexsym.ins +2020/12/31 | 503965 | macros/latex/base/ltshipout-doc.pdf +2020/12/31 | 500919 | macros/latex/base/ltnews31.pdf +2020/12/31 | 50033 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma +2020/12/31 | 49972 | macros/latex/base/ltfssaxes.dtx +2020/12/31 | 4956 | macros/luatex/generic/luaotfload/luaotfload-dvi.lua +2020/12/31 | 4952 | macros/latex/base/lthyphen.dtx +2020/12/31 | 493305 | macros/luatex/generic/luaotfload/luaotfload-latex.pdf +2020/12/31 | 491246 | macros/latex/base/ltnews30.pdf +2020/12/31 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +2020/12/31 | 48645 | macros/latex/base/ltplain.dtx +2020/12/31 | 483100 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma +2020/12/31 | 479501 | macros/latex/base/docstrip.pdf +2020/12/31 | 47850 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma +2020/12/31 | 47704 | macros/latex/base/lttab.dtx +2020/12/31 | 4762 | macros/latex/base/ltlength.dtx +2020/12/31 | 475842 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma +2020/12/31 | 474 | macros/latex/contrib/biblatex/latex/lbx/swissgerman.lbx +2020/12/31 | 4740 | macros/luatex/generic/lualibs/README.md +2020/12/31 | 47020 | macros/latex/contrib/biblatex/latex/lbx/spanish.lbx +2020/12/31 | 46876 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma +2020/12/31 | 4611 | macros/latex/contrib/biblatex/latex/bbx/reading.bbx +2020/12/31 | 460885 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma +2020/12/31 | 45842 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma +2020/12/31 | 4578 | macros/latex/contrib/biblatex/latex/cbx/numeric.cbx +2020/12/31 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +2020/12/31 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc +2020/12/31 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc +2020/12/31 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc +2020/12/31 | 45570 | macros/latex/contrib/biblatex/CHANGES.md +2020/12/31 | 45543 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma +2020/12/31 | 45246 | macros/latex/base/ltspace.dtx +2020/12/31 | 45200 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma +2020/12/31 | 45070 | macros/latex/contrib/biblatex/latex/lbx/russian.lbx +2020/12/31 | 44740 | macros/latex/contrib/biblatex/latex/lbx/lithuanian.lbx +2020/12/31 | 44468 | macros/latex/contrib/biblatex/latex/lbx/bulgarian.lbx +2020/12/31 | 44157 | macros/latex/contrib/biblatex/latex/lbx/ukrainian.lbx +2020/12/31 | 43947 | macros/luatex/generic/luaotfload/fontloader-util-str.lua +2020/12/31 | 4392 | macros/latex/base/ec.ins +2020/12/31 | 43637 | macros/latex/base/cmfonts.fdd +2020/12/31 | 43608 | macros/latex/contrib/biblatex/latex/lbx/latvian.lbx +2020/12/31 | 4357396 | macros/latex/base/source2e.pdf +2020/12/31 | 43398 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma +2020/12/31 | 433004 | macros/latex/base/ltnews29.pdf +2020/12/31 | 4326 | macros/latex/base/cmfonts.ins +2020/12/31 | 43151 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma +2020/12/31 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma +2020/12/31 | 4304 | macros/latex/base/ltalloc.dtx +2020/12/31 | 42941 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma +2020/12/31 | 42708 | macros/latex/base/changes.old.txt +2020/12/31 | 426 | macros/latex/contrib/biblatex/doc/examples/97-annotations.bib +2020/12/31 | 4261 | macros/latex/contrib/biblatex/latex/cbx/alphabetic.cbx +2020/12/31 | 42572 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma +2020/12/31 | 4256 | macros/latex/base/newdc.ins +2020/12/31 | 4240 | macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua +2020/12/31 | 42288 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma +2020/12/31 | 4223 | macros/latex/base/docstrip.ins +2020/12/31 | 4221 | macros/latex/base/latex209.ins +2020/12/31 | 418342 | macros/latex/base/fntguide.pdf +2020/12/31 | 41758 | macros/luatex/generic/luaotfload/fontloader-l-table.lua +2020/12/31 | 4171 | macros/latex/base/ltnews19.tex +2020/12/31 | 41599 | macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +2020/12/31 | 41587 | macros/latex/base/ltboxes.dtx +2020/12/31 | 41319 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma +2020/12/31 | 41306 | macros/luatex/generic/lualibs/lualibs-unicode.lua +2020/12/31 | 41303 | macros/luatex/generic/luaotfload/fontloader-l-unicode.lua +2020/12/31 | 41011 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma +2020/12/31 | 4089 | macros/latex/base/classes.ins +2020/12/31 | 40877 | macros/latex/base/ltfinal.dtx +2020/12/31 | 4080 | macros/latex/base/lablst.tex +2020/12/31 | 4047 | macros/luatex/generic/luaotfload/luaotfload-fallback.lua +2020/12/31 | 4032 | macros/latex/contrib/biblatex/latex/bbx/debug.bbx +2020/12/31 | 40030 | macros/luatex/generic/luaotfload/filegraph.pdf +2020/12/31 | 399035 | macros/latex/base/usrguide.pdf +2020/12/31 | 39823 | macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf +2020/12/31 | 3976 | macros/latex/contrib/biblatex/latex/cbx/authoryear.cbx +2020/12/31 | 3962 | macros/latex/base/olddc.ins +2020/12/31 | 39565 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma +2020/12/31 | 39540 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma +2020/12/31 | 392499 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma +2020/12/31 | 39244 | macros/latex/base/ltmath.dtx +2020/12/31 | 391 | macros/latex/contrib/biblatex/doc/examples/90-related-entries.tex +2020/12/31 | 39038 | macros/latex/contrib/biblatex/latex/lbx/magyar.lbx +2020/12/31 | 39026 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex +2020/12/31 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57260.tar.xz +2020/12/31 | 38735 | macros/latex/base/latex209.dtx +2020/12/31 | 38703 | macros/luatex/generic/luaotfload/fontloader-l-lpeg.lua +2020/12/31 | 38558 | macros/latex/contrib/biblatex/latex/lbx/english.lbx +2020/12/31 | 385524 | systems/texlive/tlnet/archive/biblatex-nature.doc.r57262.tar.xz +2020/12/31 | 3850 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ibid.cbx +2020/12/31 | 38038 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma +2020/12/31 | 37980 | macros/latex/base/latexchanges.tex +2020/12/31 | 3786 | macros/latex/contrib/biblatex/latex/blx-unicode.def +2020/12/31 | 3784 | macros/luatex/generic/luaotfload/README.md +2020/12/31 | 3783 | macros/latex/base/tulm.ins +2020/12/31 | 3776 | systems/texlive/tlnet/archive/nomencl.r57263.tar.xz +2020/12/31 | 3731 | macros/latex/base/ltlogos.dtx +2020/12/31 | 372555 | macros/latex/base/clsguide.pdf +2020/12/31 | 37232 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma +2020/12/31 | 37230 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma +2020/12/31 | 3713 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle.tex +2020/12/31 | 368226 | macros/latex/base/ltnews28.pdf +2020/12/31 | 36703 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma +2020/12/31 | 36663 | macros/latex/contrib/biblatex/latex/lbx/finnish.lbx +2020/12/31 | 36597 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma +2020/12/31 | 362839 | macros/latex/base/ltnews26.pdf +2020/12/31 | 362219 | macros/latex/base/changes.txt +2020/12/31 | 36154 | macros/latex/base/ltlists.dtx +2020/12/31 | 36005 | macros/latex/base/ltnews18.pdf +2020/12/31 | 3588 | macros/latex/contrib/biblatex/doc/examples/22-indexing-subentry.tex +2020/12/31 | 35469 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma +2020/12/31 | 35308 | macros/latex/contrib/biblatex/latex/lbx/catalan.lbx +2020/12/31 | 35299 | macros/latex/contrib/biblatex/latex/lbx/greek.lbx +2020/12/31 | 35221 | macros/latex/base/ltdirchk.dtx +2020/12/31 | 3520 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix.tex +2020/12/31 | 351586 | macros/latex/base/slides.pdf +2020/12/31 | 3514 | macros/latex/base/README.md +2020/12/31 | 35039 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma +2020/12/31 | 34862 | macros/luatex/generic/luaotfload/fontloader-font-ott.lua +2020/12/31 | 3454 | macros/latex/contrib/biblatex/latex/cbx/authortitle-ticomp.cbx +2020/12/31 | 34452 | macros/latex/contrib/biblatex/latex/lbx/french.lbx +2020/12/31 | 3437 | macros/latex/contrib/biblatex/latex/bbx/authortitle.bbx +2020/12/31 | 3436 | macros/latex/base/makeindx.ins +2020/12/31 | 343641 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma +2020/12/31 | 34195 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma +2020/12/31 | 3403 | macros/latex/base/proc.ins +2020/12/31 | 3374 | macros/latex/base/letter.ins +2020/12/31 | 3369 | macros/latex/base/ltoutenc.ins +2020/12/31 | 3340 | macros/latex/base/exscale.ins +2020/12/31 | 33387 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma +2020/12/31 | 33256 | macros/latex/base/ltnews32.tex +2020/12/31 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma +2020/12/31 | 331074 | macros/latex/base/utf8ienc.pdf +2020/12/31 | 33082 | macros/latex/contrib/biblatex/latex/lbx/serbianc.lbx +2020/12/31 | 33062 | macros/latex/contrib/biblatex/latex/lbx/czech.lbx +2020/12/31 | 33035 | macros/luatex/generic/luaotfload/fontloader-font-otl.lua +2020/12/31 | 330226 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma +2020/12/31 | 33007 | macros/latex/contrib/biblatex/latex/lbx/estonian.lbx +2020/12/31 | 32997 | macros/latex/contrib/biblatex/latex/lbx/german.lbx +2020/12/31 | 3294 | macros/latex/base/bugs.txt +2020/12/31 | 328754 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-biber.pdf +2020/12/31 | 3287334 | macros/luatex/generic/luaotfload/luaotfload-characters.lua +2020/12/31 | 3273 | macros/latex/contrib/biblatex/doc/examples/95-customlists.tex +2020/12/31 | 327370 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1-bibtex.pdf +2020/12/31 | 32647 | macros/latex/base/ltsect.dtx +2020/12/31 | 32598 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma +2020/12/31 | 32597 | macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +2020/12/31 | 3256 | systems/texlive/tlnet/archive/biblatex-nature.r57262.tar.xz +2020/12/31 | 32359 | macros/latex/contrib/biblatex/latex/blx-dm.def +2020/12/31 | 32164 | macros/latex/base/latexrelease.dtx +2020/12/31 | 32154 | macros/latex/contrib/biblatex/latex/lbx/slovak.lbx +2020/12/31 | 3206 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid.tex +2020/12/31 | 32068 | systems/texlive/tlnet/archive/gost.source.r57267.tar.xz +2020/12/31 | 31993 | macros/latex/contrib/biblatex/latex/lbx/polish.lbx +2020/12/31 | 319754 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma +2020/12/31 | 319324 | systems/texlive/tlnet/archive/archivo.r57261.tar.xz +2020/12/31 | 3182 | macros/latex/base/unpack.ins +2020/12/31 | 31553 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma +2020/12/31 | 31390 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma +2020/12/31 | 31350 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma +2020/12/31 | 31298 | macros/luatex/generic/luaotfload/fontloader-font-one.lua +2020/12/31 | 31281 | macros/latex/contrib/biblatex/doc/examples/90-related-entries-biber.pdf +2020/12/31 | 31273 | macros/latex/contrib/biblatex/latex/lbx/slovene.lbx +2020/12/31 | 31247 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma +2020/12/31 | 31151 | macros/luatex/generic/luaotfload/luaotfload-configuration.lua +2020/12/31 | 31124 | macros/latex/contrib/biblatex/latex/lbx/turkish.lbx +2020/12/31 | 30999 | macros/luatex/generic/luaotfload/luaotfload-parsers.lua +2020/12/31 | 309293 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma +2020/12/31 | 30890 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma +2020/12/31 | 30679 | macros/latex/contrib/biblatex/latex/lbx/basque.lbx +2020/12/31 | 30596 | macros/latex/contrib/biblatex/latex/lbx/dutch.lbx +2020/12/31 | 305786 | macros/latex/base/letter.pdf +2020/12/31 | 305339 | macros/latex/base/ltluatex.pdf +2020/12/31 | 3049 | macros/luatex/generic/lualibs/NEWS +2020/12/31 | 30457 | macros/latex/base/ltnews31.tex +2020/12/31 | 3036 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp.tex +2020/12/31 | 302836 | macros/latex/base/ltnews22.pdf +2020/12/31 | 30087 | macros/latex/contrib/biblatex/latex/lbx/danish.lbx +2020/12/31 | 29931 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma +2020/12/31 | 295529 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma +2020/12/31 | 294900 | macros/latex/base/inputenc.pdf +2020/12/31 | 29410 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma +2020/12/31 | 2934 | macros/latex/contrib/biblatex/latex/cbx/authortitle-tcomp.cbx +2020/12/31 | 29318 | macros/latex/contrib/biblatex/latex/lbx/portuguese.lbx +2020/12/31 | 29263 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma +2020/12/31 | 29247 | macros/latex/contrib/biblatex/latex/lbx/norsk.lbx +2020/12/31 | 29194 | macros/latex/base/ltfntcmd.dtx +2020/12/31 | 29100 | macros/latex/contrib/biblatex/latex/lbx/brazilian.lbx +2020/12/31 | 29072 | macros/latex/contrib/biblatex/latex/lbx/croatian.lbx +2020/12/31 | 29002 | macros/luatex/generic/luaotfload/luaotfload-features.lua +2020/12/31 | 2899 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid.tex +2020/12/31 | 2898 | macros/latex/base/syntonly.ins +2020/12/31 | 28976 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma +2020/12/31 | 2895 | macros/latex/base/nfssfont.ins +2020/12/31 | 2894 | macros/latex/base/graphpap.ins +2020/12/31 | 2894 | macros/latex/base/fix-cm.ins +2020/12/31 | 2893 | macros/latex/contrib/biblatex/latex/lbx/british.lbx +2020/12/31 | 2893 | macros/latex/contrib/biblatex/latex/cbx/authortitle.cbx +2020/12/31 | 2892 | macros/latex/base/alltt.ins +2020/12/31 | 2890 | macros/latex/base/ifthen.ins +2020/12/31 | 28621 | macros/latex/contrib/biblatex/latex/lbx/galician.lbx +2020/12/31 | 28396601 | install/macros/latex/latex-base.tds.zip +2020/12/31 | 283901 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma +2020/12/31 | 2833 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp.tex +2020/12/31 | 283318 | macros/latex/base/ltnews20.pdf +2020/12/31 | 28228 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma +2020/12/31 | 280109 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma +2020/12/31 | 280078 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-biber.pdf +2020/12/31 | 27946 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma +2020/12/31 | 27943154 | macros/latex/base.zip +2020/12/31 | 27850 | macros/luatex/generic/lualibs/lualibs.dtx +2020/12/31 | 277799 | macros/latex/contrib/biblatex/doc/examples/50-style-authoryear-bibtex.pdf +2020/12/31 | 277795 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-biber.pdf +2020/12/31 | 276 | macros/latex/contrib/biblatex/latex/lbx/austrian.lbx +2020/12/31 | 275 | macros/luatex/generic/luaotfload/luaotfload-main.lua +2020/12/31 | 275259 | macros/latex/contrib/biblatex/doc/examples/60-style-authortitle-bibtex.pdf +2020/12/31 | 274459 | macros/latex/base/ltnews23.pdf +2020/12/31 | 274164 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-biber.pdf +2020/12/31 | 2738 | macros/latex/base/tex2.txt +2020/12/31 | 273584 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-biber.pdf +2020/12/31 | 2733 | macros/latex/base/ltpageno.dtx +2020/12/31 | 273393 | install/macros/luatex/generic/lualibs.tds.zip +2020/12/31 | 272786 | macros/latex/contrib/biblatex/doc/examples/73-style-verbose-inote-bibtex.pdf +2020/12/31 | 272203 | macros/latex/contrib/biblatex/doc/examples/75-style-verbose-trad2-bibtex.pdf +2020/12/31 | 27212 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma +2020/12/31 | 272064 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-biber.pdf +2020/12/31 | 27199 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma +2020/12/31 | 27194 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma +2020/12/31 | 27124 | macros/latex/base/ltxcheck.tex +2020/12/31 | 270799 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-biber.pdf +2020/12/31 | 2706 | macros/latex/base/idx.tex +2020/12/31 | 270652 | macros/latex/contrib/biblatex/doc/examples/71-style-verbose-ibid-bibtex.pdf +2020/12/31 | 27042 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma +2020/12/31 | 270391 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-biber.pdf +2020/12/31 | 269420 | macros/latex/contrib/biblatex/doc/examples/76-style-verbose-trad3-bibtex.pdf +2020/12/31 | 268908 | macros/latex/contrib/biblatex/doc/examples/72-style-verbose-note-bibtex.pdf +2020/12/31 | 2688 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric.tex +2020/12/31 | 268065 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-biber.pdf +2020/12/31 | 2667 | macros/luatex/generic/luaotfload/fontloader-font-vfc.lua +2020/12/31 | 266542 | macros/latex/contrib/biblatex/doc/examples/70-style-verbose-bibtex.pdf +2020/12/31 | 265702 | macros/luatex/generic/lualibs.zip +2020/12/31 | 26536 | systems/texlive/tlnet/archive/luamplib.source.r57266.tar.xz +2020/12/31 | 264505 | macros/latex/base/cmfonts.pdf +2020/12/31 | 2635 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse.tex +2020/12/31 | 262059 | macros/latex/base/fix-cm.pdf +2020/12/31 | 26169 | macros/latex/contrib/biblatex/latex/lbx/swedish.lbx +2020/12/31 | 2616450 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma +2020/12/31 | 25869 | biblio/biber/documentation/Changes +2020/12/31 | 258692 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma +2020/12/31 | 2585 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp.tex +2020/12/31 | 2582 | macros/luatex/generic/luaotfload/luaotfload-suppress.lua +2020/12/31 | 2580 | macros/latex/contrib/biblatex/doc/examples/80-style-reading.tex +2020/12/31 | 2572 | macros/latex/contrib/biblatex/latex/cbx/numeric-verb.cbx +2020/12/31 | 25680 | macros/latex/contrib/biblatex/latex/bbx/standard.bbx +2020/12/31 | 25609 | macros/latex/contrib/biblatex/latex/lbx/icelandic.lbx +2020/12/31 | 25336 | macros/luatex/generic/luaotfload/luaotfload-filelist.lua +2020/12/31 | 25296 | macros/latex/contrib/biblatex/doc/examples/96-dates-biber.pdf +2020/12/31 | 252645 | macros/latex/base/ltnews24.pdf +2020/12/31 | 25091 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma +2020/12/31 | 2506 | macros/luatex/generic/luaotfload/luaotfload-scripts.lua +2020/12/31 | 25014 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma +2020/12/31 | 250140 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma +2020/12/31 | 2495180 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma +2020/12/31 | 246195 | macros/latex/base/latexrelease.pdf +2020/12/31 | 246067 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf +2020/12/31 | 24566 | macros/luatex/generic/luaotfload/fontloader-font-ocl.lua +2020/12/31 | 245466 | macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf +2020/12/31 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-bibtex.pdf +2020/12/31 | 244291 | macros/latex/contrib/biblatex/doc/examples/80-style-reading-biber.pdf +2020/12/31 | 24371 | macros/latex/contrib/biblatex/latex/blx-bibtex.def +2020/12/31 | 2434 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single.tex +2020/12/31 | 243464 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma +2020/12/31 | 24270384 | systems/texlive/tlnet/install-tl.zip +2020/12/31 | 24027 | macros/latex/contrib/biblatex/doc/examples/94-labelprefix-biber.pdf +2020/12/31 | 24016 | macros/latex/base/lterror.dtx +2020/12/31 | 239758 | macros/latex/base/ltnews27.pdf +2020/12/31 | 2395 | macros/latex/contrib/biblatex/doc/examples/04-delimiters.tex +2020/12/31 | 2388 | macros/latex/contrib/biblatex/latex/cbx/debug.cbx +2020/12/31 | 23866 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma +2020/12/31 | 23858 | macros/latex/contrib/biblatex/latex/lbx/serbian.lbx +2020/12/31 | 23652 | macros/latex/base/ltnews30.tex +2020/12/31 | 23521 | macros/latex/base/fix-cm.dtx +2020/12/31 | 235073 | macros/latex/base/ltnews19.pdf +2020/12/31 | 23386 | macros/latex/base/lppl.tex +2020/12/31 | 233492 | macros/latex/base/ltnews21.pdf +2020/12/31 | 23265 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma +2020/12/31 | 232390 | macros/latex/base/latexchanges.pdf +2020/12/31 | 231839 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma +2020/12/31 | 23181 | macros/latex/contrib/biblatex/latex/lbx/italian.lbx +2020/12/31 | 22676 | macros/latex/base/ltcounts.dtx +2020/12/31 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-bibtex.pdf +2020/12/31 | 225925 | macros/latex/contrib/biblatex/doc/examples/53-style-authoryear-icomp-biber.pdf +2020/12/31 | 2257 | macros/latex/contrib/biblatex/latex/cbx/alphabetic-verb.cbx +2020/12/31 | 2257956 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz +2020/12/31 | 22457 | macros/latex/base/cfgguide.tex +2020/12/31 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-bibtex.pdf +2020/12/31 | 222705 | macros/latex/contrib/biblatex/doc/examples/63-style-authortitle-icomp-biber.pdf +2020/12/31 | 220848 | systems/texlive/tlnet/archive/skeldoc.doc.r57264.tar.xz +2020/12/31 | 220388 | macros/latex/base/modguide.pdf +2020/12/31 | 220217 | macros/latex/base/cfgguide.pdf +2020/12/31 | 22019 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma +2020/12/31 | 2190 | macros/latex/contrib/biblatex/latex/blx-natbib.def +2020/12/31 | 21857 | macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +2020/12/31 | 21707 | macros/latex/contrib/biblatex/doc/examples/91-sorting-schemes-biber.pdf +2020/12/31 | 216997 | macros/latex/base/cyrguide.pdf +2020/12/31 | 21696 | macros/luatex/generic/luaotfload/scripts-demo.pdf +2020/12/31 | 216877 | macros/latex/base/proc.pdf +2020/12/31 | 215102 | macros/latex/base/ltxdoc.pdf +2020/12/31 | 214710 | macros/latex/base/slifonts.pdf +2020/12/31 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-bibtex.pdf +2020/12/31 | 213637 | macros/latex/contrib/biblatex/doc/examples/51-style-authoryear-ibid-biber.pdf +2020/12/31 | 2126 | macros/latex/contrib/biblatex/latex/blx-mcite.def +2020/12/31 | 212473 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma +2020/12/31 | 212400 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma +2020/12/31 | 21167 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma +2020/12/31 | 210603 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma +2020/12/31 | 207981 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma +2020/12/31 | 207853 | macros/latex/contrib/biblatex/doc/examples/02-annotations-biber.pdf +2020/12/31 | 207478 | macros/latex/contrib/biblatex/doc/examples/02-annotations-bibtex.pdf +2020/12/31 | 205396 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma +2020/12/31 | 205351 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma +2020/12/31 | 205213 | macros/latex/base/ifthen.pdf +2020/12/31 | 20471 | macros/latex/base/ltnews.cls +2020/12/31 | 20434 | macros/latex/base/lgc2.err +2020/12/31 | 204016 | macros/latex/base/doc.dtx +2020/12/31 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-bibtex.pdf +2020/12/31 | 203055 | macros/latex/contrib/biblatex/doc/examples/61-style-authortitle-ibid-biber.pdf +2020/12/31 | 202753 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma +2020/12/31 | 202451 | macros/latex/base/nfssfont.pdf +2020/12/31 | 20132 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma +2020/12/31 | 200075 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-biber.pdf +2020/12/31 | 199606 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma +2020/12/31 | 1994 | macros/latex/contrib/biblatex/doc/examples/10-references-per-section.tex +2020/12/31 | 19944 | macros/luatex/generic/luaotfload/fontloader-font-def.lua +2020/12/31 | 199318 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic-bibtex.pdf +2020/12/31 | 1988 | macros/latex/contrib/biblatex/doc/examples/40-style-alphabetic.tex +2020/12/31 | 1985832 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma +2020/12/31 | 19847 | macros/luatex/generic/luaotfload/NEWS +2020/12/31 | 198077 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma +2020/12/31 | 19781 | macros/latex/contrib/biblatex/latex/lbx/nynorsk.lbx +2020/12/31 | 196326 | macros/latex/base/ltnews25.pdf +2020/12/31 | 195877 | macros/latex/base/exscale.pdf +2020/12/31 | 19570 | macros/luatex/generic/luaotfload/fontloader-font-map.lua +2020/12/31 | 195612 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma +2020/12/31 | 19547 | macros/luatex/generic/luaotfload/luaotfload-init.lua +2020/12/31 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-bibtex.pdf +2020/12/31 | 195323 | macros/latex/contrib/biblatex/doc/examples/64-style-authortitle-terse-biber.pdf +2020/12/31 | 1942 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1.tex +2020/12/31 | 194176 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma +2020/12/31 | 19409 | macros/luatex/generic/lualibs/lualibs-os.lua +2020/12/31 | 1938 | macros/latex/base/minimal.cls +2020/12/31 | 19387619 | systems/texlive/tlnet/install-tl-windows.exe +2020/12/31 | 1936733 | install/macros/luatex/generic/luaotfload.tds.zip +2020/12/31 | 193531 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma +2020/12/31 | 1927005 | macros/luatex/generic/luaotfload.zip +2020/12/31 | 192297 | macros/latex/base/latexsym.pdf +2020/12/31 | 191527 | macros/latex/base/ltx3info.pdf +2020/12/31 | 19064 | macros/latex/base/ltxdoc.dtx +2020/12/31 | 19040 | macros/latex/base/lppl.txt +2020/12/31 | 18941 | macros/latex/base/ltnews29.tex +2020/12/31 | 18836 | systems/texlive/tlnet/archive/nomencl.source.r57263.tar.xz +2020/12/31 | 1876 | macros/latex/contrib/biblatex/doc/examples/11-references-by-section.tex +2020/12/31 | 18717 | macros/luatex/generic/luaotfload/fontloader-font-onr.lua +2020/12/31 | 187105 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-bibtex.pdf +2020/12/31 | 186808 | macros/latex/contrib/biblatex/doc/examples/31-style-numeric-comp-biber.pdf +2020/12/31 | 18678005 | macros/latex/contrib/biblatex.zip +2020/12/31 | 18645 | macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +2020/12/31 | 1860 | systems/texlive/tlnet/archive/collection-fontsextra.r57261.tar.xz +2020/12/31 | 18421 | macros/luatex/generic/luaotfload/fontloader-font-ota.lua +2020/12/31 | 18407 | macros/latex/base/nfssfont.dtx +2020/12/31 | 18305 | macros/latex/base/ifthen.dtx +2020/12/31 | 18300 | macros/latex/base/ltx3info.tex +2020/12/31 | 182024 | macros/luatex/generic/luaotfload/fontloader-font-ots.lua +2020/12/31 | 1818 | macros/latex/contrib/biblatex/latex/bbx/numeric.bbx +2020/12/31 | 181787 | macros/latex/base/syntonly.pdf +2020/12/31 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-bibtex.pdf +2020/12/31 | 181606 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb-biber.pdf +2020/12/31 | 1812 | macros/luatex/generic/luaotfload/luaotfload.sty +2020/12/31 | 180 | macros/latex/base/ltfilehook-doc.tex +2020/12/31 | 1808 | macros/latex/contrib/biblatex/latex/cbx/draft.cbx +2020/12/31 | 18074 | macros/luatex/generic/luaotfload/luaotfload.conf.rst +2020/12/31 | 180252 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma +2020/12/31 | 18009 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma +2020/12/31 | 179 | macros/latex/base/ltshipout-doc.tex +2020/12/31 | 179341 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma +2020/12/31 | 17875 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma +2020/12/31 | 1781 | macros/latex/contrib/biblatex/doc/examples/97-annotations.tex +2020/12/31 | 177 | macros/latex/base/lthooks-doc.tex +2020/12/31 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-bibtex.pdf +2020/12/31 | 177233 | macros/latex/contrib/biblatex/doc/examples/30-style-numeric-biber.pdf +2020/12/31 | 1764668 | systems/texlive/tlnet/archive/gost.doc.r57267.tar.xz +2020/12/31 | 175629 | macros/latex/base/ltoutput.dtx +2020/12/31 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-bibtex.pdf +2020/12/31 | 175130 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword-biber.pdf +2020/12/31 | 17496 | macros/latex/base/cyrguide.tex +2020/12/31 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-bibtex.pdf +2020/12/31 | 174634 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category-biber.pdf +2020/12/31 | 17456 | systems/texlive/tlnet/archive/gost.r57267.tar.xz +2020/12/31 | 1731 | macros/latex/contrib/biblatex/latex/bbx/alphabetic.bbx +2020/12/31 | 173079 | macros/latex/base/alltt.pdf +2020/12/31 | 172216 | macros/latex/base/tlc2.err +2020/12/31 | 171712 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-biber.pdf +2020/12/31 | 171031 | macros/latex/contrib/biblatex/doc/examples/21-indexing-multiple-bibtex.pdf +2020/12/31 | 170888 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57260.tar.xz +2020/12/31 | 170519 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-biber.pdf +2020/12/31 | 170214 | macros/latex/base/docstrip.dtx +2020/12/31 | 169 | macros/latex/contrib/biblatex/latex/lbx/american.lbx +2020/12/31 | 1699739 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma +2020/12/31 | 169812 | macros/latex/contrib/biblatex/doc/examples/20-indexing-single-bibtex.pdf +2020/12/31 | 1694 | macros/latex/base/small2e.tex +2020/12/31 | 1682 | macros/latex/contrib/biblatex/doc/examples/14-references-by-category.tex +2020/12/31 | 16810760 | systems/texlive/tlnet/tlpkg/texlive.tlpdb +2020/12/31 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-bibtex.pdf +2020/12/31 | 167962 | macros/latex/contrib/biblatex/doc/examples/01-introduction-biber.pdf +2020/12/31 | 16675 | macros/luatex/generic/luaotfload/luaotfload-latex.tex +2020/12/31 | 16647 | macros/latex/contrib/biblatex/doc/examples/97-annotations-biber.pdf +2020/12/31 | 165760 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma +2020/12/31 | 165558 | macros/latex/base/lthooks.dtx +2020/12/31 | 16548 | macros/luatex/generic/luaotfload/luaotfload.conf.5 +2020/12/31 | 164947 | macros/latex/base/tlc2.pdf +2020/12/31 | 163 | macros/latex/contrib/biblatex/latex/lbx/canadian.lbx +2020/12/31 | 16234 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma +2020/12/31 | 16234 | macros/latex/base/modguide.tex +2020/12/31 | 162264 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma +2020/12/31 | 16216 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma +2020/12/31 | 1612 | systems/texlive/tlnet/archive/xurl.r57265.tar.xz +2020/12/31 | 161065 | macros/latex/base/ltnews13.pdf +2020/12/31 | 160667 | macros/latex/base/makeindx.pdf +2020/12/31 | 159 | macros/latex/contrib/biblatex/doc/examples/95-customlists.dbx +2020/12/31 | 159922 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma +2020/12/31 | 1598244 | macros/latex/contrib/biblatex/doc/biblatex.pdf +2020/12/31 | 15954 | macros/luatex/generic/luaotfload/luaotfload-colors.lua +2020/12/31 | 15940 | macros/luatex/generic/luaotfload/luaotfload-tool.rst +2020/12/31 | 158307 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-biber.pdf +2020/12/31 | 157684 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-biber.pdf +2020/12/31 | 157659 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-biber.pdf +2020/12/31 | 157616 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf +2020/12/31 | 157181 | macros/latex/base/ltnews05.pdf +2020/12/31 | 15701 | macros/latex/base/slifonts.fdd +2020/12/31 | 156546 | macros/latex/base/tulm.pdf +2020/12/31 | 156540 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf +2020/12/31 | 156540 | macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf +2020/12/31 | 156277 | macros/latex/base/graphpap.pdf +2020/12/31 | 15623 | macros/latex/base/ltxref.dtx +2020/12/31 | 155735 | macros/latex/base/classes.dtx +2020/12/31 | 1549 | macros/latex/contrib/biblatex/doc/examples/92-bibliographylists.tex +2020/12/31 | 1546 | macros/latex/contrib/biblatex/doc/examples/32-style-numeric-verb.tex +2020/12/31 | 154135 | macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +2020/12/31 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 +2020/12/31 | 1532144 | macros/latex/base/encguide.pdf +2020/12/31 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 +2020/12/31 | 152375 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma +2020/12/31 | 152328 | systems/texlive/tlnet/archive/luamplib.doc.r57266.tar.xz +2020/12/31 | 152156 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma +2020/12/31 | 15196 | macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua +2020/12/31 | 151347 | macros/latex/base/manual.pdf +2020/12/31 | 150907 | macros/latex/base/ltnews14.pdf +2020/12/31 | 15068 | macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +2020/12/31 | 150020 | macros/latex/base/ltnews01.pdf +2020/12/31 | 149838 | macros/latex/base/ltnews17.pdf +2020/12/31 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-bibtex.pdf +2020/12/31 | 149733 | macros/latex/contrib/biblatex/doc/examples/81-style-draft-biber.pdf +2020/12/31 | 149679 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf +2020/12/31 | 14918 | macros/latex/base/source2e.tex +2020/12/31 | 14892 | macros/latex/base/ltnews28.tex +2020/12/31 | 148860 | macros/latex/contrib/biblatex/doc/examples/82-style-debug-bibtex.pdf +2020/12/31 | 147946 | macros/latex/base/ltnews10.pdf +2020/12/31 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-bibtex.pdf +2020/12/31 | 147776 | macros/latex/contrib/biblatex/doc/examples/66-style-authortitle-ticomp-biber.pdf +2020/12/31 | 147333 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma +2020/12/31 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-bibtex.pdf +2020/12/31 | 147304 | macros/latex/contrib/biblatex/doc/examples/52-style-authoryear-comp-biber.pdf +2020/12/31 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 +2020/12/31 | 145308 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma +2020/12/31 | 145163 | macros/latex/base/ltoutenc.dtx +2020/12/31 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +2020/12/31 | 144482 | macros/latex/base/ltnews08.pdf +2020/12/31 | 14440 | macros/latex/base/ltbibl.dtx +2020/12/31 | 14421 | macros/latex/base/lppl-1-2.txt +2020/12/31 | 14356 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma +2020/12/31 | 14341 | macros/latex/base/lppl-1-1.txt +2020/12/31 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-bibtex.pdf +2020/12/31 | 143176 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp-biber.pdf +2020/12/31 | 1416387 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma +2020/12/31 | 14153 | macros/latex/contrib/biblatex/doc/examples/74-style-verbose-trad1.tex +2020/12/31 | 1409 | macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed.tex +2020/12/31 | 13977 | macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua +2020/12/31 | 138219 | macros/latex/base/lb2.pdf +2020/12/31 | 1381 | macros/latex/base/legal.txt +2020/12/31 | 1380782 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma +2020/12/31 | 137919 | macros/latex/base/ltnews12.pdf +2020/12/31 | 13788 | macros/luatex/generic/luaotfload/luaotfload.lua +2020/12/31 | 13703 | macros/latex/base/ltexpl.dtx +2020/12/31 | 13625 | macros/luatex/generic/lualibs/lualibs-util-dim.lua +2020/12/31 | 136159 | macros/latex/base/webcomp.pdf +2020/12/31 | 13500 | macros/luatex/generic/luaotfload/fontloader-font-shp.lua +2020/12/31 | 134863 | macros/luatex/generic/luaotfload/luaotfload-database.lua +2020/12/31 | 13476 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma +2020/12/31 | 134751 | macros/latex/base/ltnews02.pdf +2020/12/31 | 134742 | macros/latex/base/ltnews03.pdf +2020/12/31 | 134710 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma +2020/12/31 | 1346 | macros/latex/contrib/biblatex/doc/examples/65-style-authortitle-tcomp.tex +2020/12/31 | 13468 | macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +2020/12/31 | 1342 | macros/latex/base/ltnews18.tex +2020/12/31 | 1340 | macros/latex/contrib/biblatex/doc/examples/12-references-by-segment.tex +2020/12/31 | 13379 | macros/latex/contrib/biblatex/latex/blx-compat.def +2020/12/31 | 1334 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp.tex +2020/12/31 | 133138 | macros/latex/base/ltnews06.pdf +2020/12/31 | 13305 | macros/latex/base/proc.dtx +2020/12/31 | 132 | macros/latex/contrib/biblatex/latex/lbx/portuges.lbx +2020/12/31 | 132465 | macros/latex/contrib/biblatex/doc/examples/biblatex-examples.bltxml +2020/12/31 | 132465 | macros/latex/contrib/biblatex/biber/bltxml/biblatex-examples.bltxml +2020/12/31 | 131918 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma +2020/12/31 | 131468 | macros/luatex/generic/lualibs/lualibs-basic-merged.lua +2020/12/31 | 131230 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma +2020/12/31 | 1311 | macros/latex/contrib/biblatex/doc/examples/13-references-by-keyword.tex +2020/12/31 | 130687 | macros/latex/base/ltnews16.pdf +2020/12/31 | 1304654 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma +2020/12/31 | 129 | macros/latex/contrib/biblatex/latex/lbx/USenglish.lbx +2020/12/31 | 12946 | macros/latex/base/manual.err +2020/12/31 | 128 | macros/latex/contrib/biblatex/latex/lbx/brazil.lbx +2020/12/31 | 128863 | macros/latex/base/ltclass.dtx +2020/12/31 | 1287 | macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2.tex +2020/12/31 | 128772 | macros/latex/base/ltnews04.pdf +2020/12/31 | 1284 | macros/latex/contrib/biblatex/latex/cbx/authortitle-terse.cbx +2020/12/31 | 1282239 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma +2020/12/31 | 127 | macros/latex/contrib/biblatex/latex/lbx/UKenglish.lbx +2020/12/31 | 127 | macros/latex/contrib/biblatex/latex/lbx/slovenian.lbx +2020/12/31 | 12745 | macros/luatex/generic/luaotfload/fontloader-basics-gen.lua +2020/12/31 | 12707 | macros/luatex/generic/luaotfload/luaotfload-tool.1 +2020/12/31 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-bibtex.pdf +2020/12/31 | 126042 | macros/latex/contrib/biblatex/doc/examples/62-style-authortitle-comp-biber.pdf +2020/12/31 | 125 | macros/latex/contrib/biblatex/latex/lbx/hungarian.lbx +2020/12/31 | 125830 | macros/latex/base/lppl.pdf +2020/12/31 | 1253450 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma +2020/12/31 | 12521 | macros/latex/base/testpage.tex +2020/12/31 | 124029 | macros/latex/base/ltnews07.pdf +2020/12/31 | 12400 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex +2020/12/31 | 1233537 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma +2020/12/31 | 1233294 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma +2020/12/31 | 12296 | macros/latex/contrib/biblatex/doc/examples/95-customlists-biber.pdf +2020/12/31 | 12225 | macros/latex/base/ltnews24.tex +2020/12/31 | 12224 | macros/luatex/generic/luaotfload/luaotfload-notdef.lua +2020/12/31 | 122092 | macros/latex/base/ltnews15.pdf +2020/12/31 | 12120 | macros/latex/base/tulm.fdd +2020/12/31 | 120284 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma +2020/12/31 | 120222 | macros/latex/base/ltnews09.pdf +2020/12/31 | 11969 | macros/luatex/generic/lualibs/lualibs-package.lua +2020/12/31 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-bibtex.pdf +2020/12/31 | 119269 | macros/latex/contrib/biblatex/doc/examples/15-references-by-type-biber.pdf +2020/12/31 | 117724 | macros/luatex/generic/luaotfload/fontloader-font-oup.lua +2020/12/31 | 1171086 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma +2020/12/31 | 116823 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma +2020/12/31 | 11680 | systems/texlive/tlnet/archive/luamplib.r57266.tar.xz +2020/12/31 | 1160 | macros/latex/contrib/biblatex/latex/bbx/draft.bbx +2020/12/31 | 11591 | macros/latex/base/ltpage.dtx +2020/12/31 | 11552 | macros/luatex/generic/luaotfload/fontloader-util-fil.lua +2020/12/31 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini +2020/12/31 | 1151165 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma +2020/12/31 | 1150826 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma +2020/12/31 | 114806 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma +2020/12/31 | 113771 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma +2020/12/31 | 11323 | macros/luatex/generic/luaotfload/luaotfload-log.lua +2020/12/31 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-bibtex.pdf +2020/12/31 | 112916 | macros/latex/contrib/biblatex/doc/examples/18-numeric-hybrid-biber.pdf +2020/12/31 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-bibtex.pdf +2020/12/31 | 111947 | macros/latex/contrib/biblatex/doc/examples/41-style-alphabetic-verb-biber.pdf +2020/12/31 | 110513 | macros/luatex/generic/lualibs/lualibs-extended-merged.lua +2020/12/31 | 10984 | macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +2020/12/31 | 109176 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma +2020/12/31 | 1078478 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma +2020/12/31 | 107580 | macros/luatex/generic/luaotfload/fontloader-font-osd.lua +2020/12/31 | 10698 | macros/latex/base/ltnews26.tex +2020/12/31 | 106914 | macros/latex/base/inputenc.dtx +2020/12/31 | 10690 | macros/latex/base/manifest.txt +2020/12/31 | 10688 | macros/latex/base/ltnews23.tex +2020/12/31 | 10669 | macros/latex/base/ltnews22.tex +2020/12/31 | 10606 | macros/latex/base/makeindx.dtx +2020/12/31 | 105 | macros/latex/base/ltfilehook-code.tex +2020/12/31 | 104 | macros/latex/base/ltshipout-code.tex +2020/12/31 | 104936 | macros/latex/base/ltnews11.pdf +2020/12/31 | 104832 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma +2020/12/31 | 10376 | macros/latex/base/ltfsscmp.dtx +2020/12/31 | 10374 | macros/latex/contrib/biblatex/latex/cbx/numeric-comp.cbx +2020/12/31 | 1034510 | macros/latex/contrib/biblatex/doc/biblatex.tex +2020/12/31 | 103388 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma +2020/12/31 | 10327 | macros/latex/base/ltvers.dtx +2020/12/31 | 102 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ticomp.bbx +2020/12/31 | 102 | macros/latex/contrib/biblatex/doc/examples/93-nameparts.dbx +2020/12/31 | 102 | macros/latex/base/lthooks-code.tex +2020/12/31 | 102502 | macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-terse.bbx +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-tcomp.bbx +2020/12/31 | 101 | macros/latex/contrib/biblatex/latex/bbx/authortitle-icomp.bbx +2020/12/31 | 101757 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma +2020/12/31 | 101343 | macros/latex/base/lgc2.pdf +2020/12/31 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-bibtex.pdf +2020/12/31 | 101002 | macros/latex/contrib/biblatex/doc/examples/42-style-alphabetic-template-biber.pdf +2020/12/31 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-ibid.bbx +2020/12/31 | 100 | macros/latex/contrib/biblatex/latex/bbx/authortitle-comp.bbx +2020/12/31 | 10064 | macros/luatex/generic/luaotfload/fontloader-basics-nod.lua +2020/12/31 | 10053 | macros/latex/base/webcomp.err +2020/12/31 | 1004 | macros/luatex/generic/luaotfload/luaotfload-embolden.lua +2020/12/30 | 9781 | macros/luatex/generic/lualibs/lualibs-trac-inf.lua 2020/12/30 | 939 | biblio/bibtex/contrib/gost/README 2020/12/30 | 92061 | macros/luatex/generic/luamplib/luamplib.dtx 2020/12/30 | 916588 | systems/texlive/tlnet/archive/oswald.r57253.tar.xz 2020/12/30 | 914064 | info/latex2e-help-texinfo-fr/latex2e-fr.dbk 2020/12/30 | 882 | fonts/archivo/README -2020/12/30 | 87882 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma -2020/12/30 | 8783 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma -2020/12/30 | 87596 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma +2020/12/30 | 87576132 | systems/win32/w32tex/pgfcontrib.tar.xz 2020/12/30 | 8673 | macros/luatex/generic/luamplib/NEWS -2020/12/30 | 85011 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma -2020/12/30 | 835 | systems/win32/miktex/tm/packages/pr.ini 2020/12/30 | 8196 | systems/texlive/tlnet/archive/jlreq.source.r57255.tar.xz -2020/12/30 | 809095 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma -2020/12/30 | 80621 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma 2020/12/30 | 8004 | macros/latex/contrib/skeldoc/skeldoc.tex -2020/12/30 | 78764 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma -2020/12/30 | 77820 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma -2020/12/30 | 77796 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma -2020/12/30 | 7751 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma 2020/12/30 | 761505 | info/latex2e-help-texinfo-fr/latex2e-fr.info +2020/12/30 | 759306 | systems/win32/w32tex/ChangeLog 2020/12/30 | 75882 | fonts/archivo/doc/Archivo-samples.pdf -2020/12/30 | 744396 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma -2020/12/30 | 74153 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma -2020/12/30 | 73674 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma -2020/12/30 | 73242 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma -2020/12/30 | 72839 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma -2020/12/30 | 71935 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma 2020/12/30 | 716880 | info/latex2e-help-texinfo-fr/latex2e-fr.txt -2020/12/30 | 71568 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma -2020/12/30 | 70292 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma 2020/12/30 | 700 | systems/texlive/tlnet/archive/collection-luatex.r57257.tar.xz -2020/12/30 | 70011 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma 2020/12/30 | 6832 | fonts/archivo/tfm/Archiv0-MediumItalic-tosf-t1.tfm 2020/12/30 | 6832 | fonts/archivo/tfm/Archiv0-MediumItalic-tlf-t1.tfm 2020/12/30 | 6832 | fonts/archivo/tfm/Archiv0-MediumItalic-lf-t1.tfm @@ -47,33 +867,20 @@ 2020/12/30 | 6820 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tlf-t1.tfm 2020/12/30 | 6820 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-osf-t1.tfm 2020/12/30 | 6820 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-lf-t1.tfm -2020/12/30 | 680036 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma -2020/12/30 | 67766 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma -2020/12/30 | 67664 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma -2020/12/30 | 67634 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma 2020/12/30 | 668454 | biblio/bibtex/contrib/gost/doc/gost.pdf 2020/12/30 | 6648 | fonts/archivo/tfm/Archiv0-BoldItalic-tosf-t1.tfm 2020/12/30 | 6648 | fonts/archivo/tfm/Archiv0-BoldItalic-tlf-t1.tfm 2020/12/30 | 6648 | fonts/archivo/tfm/Archiv0-BoldItalic-lf-t1.tfm 2020/12/30 | 6644 | fonts/archivo/tfm/Archiv0-BoldItalic-osf-t1.tfm 2020/12/30 | 662 | macros/latex/contrib/biblatex-contrib/biblatex-nature/README.md -2020/12/30 | 66264 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma +2020/12/30 | 65991924 | systems/win32/w32tex/biblatex-biber.tar.xz 2020/12/30 | 6580 | fonts/archivo/tfm/Archiv0-Italic-tosf-t1.tfm 2020/12/30 | 6580 | fonts/archivo/tfm/Archiv0-Italic-tlf-t1.tfm 2020/12/30 | 6580 | fonts/archivo/tfm/Archiv0-Italic-lf-t1.tfm -2020/12/30 | 65803 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma 2020/12/30 | 6576 | fonts/archivo/tfm/Archiv0-Italic-osf-t1.tfm -2020/12/30 | 65470 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma +2020/12/30 | 6405 | macros/luatex/generic/lualibs/lualibs-lua.lua 2020/12/30 | 63868 | systems/texlive/tlnet/archive/uninormalize.doc.r57257.tar.xz -2020/12/30 | 63846 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma -2020/12/30 | 63801 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma -2020/12/30 | 63560 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma -2020/12/30 | 62814 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma -2020/12/30 | 624740 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma 2020/12/30 | 621761 | info/latex2e-help-texinfo-fr/latex2e-fr.texi -2020/12/30 | 61949 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma -2020/12/30 | 618635 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma -2020/12/30 | 60504 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma 2020/12/30 | 6036 | fonts/archivo/tfm/Archiv0-SemiBold-tosf-t1.tfm 2020/12/30 | 6036 | fonts/archivo/tfm/Archiv0-SemiBold-tlf-t1.tfm 2020/12/30 | 6036 | fonts/archivo/tfm/Archiv0-SemiBold-osf-t1.tfm @@ -82,10 +889,7 @@ 2020/12/30 | 6028 | fonts/archivo/tfm/Archiv0-Medium-tlf-t1.tfm 2020/12/30 | 6028 | fonts/archivo/tfm/Archiv0-Medium-osf-t1.tfm 2020/12/30 | 6028 | fonts/archivo/tfm/Archiv0-Medium-lf-t1.tfm -2020/12/30 | 59673 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma 2020/12/30 | 59523 | macros/latex/contrib/xurl.zip -2020/12/30 | 594930 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma -2020/12/30 | 59081 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma 2020/12/30 | 588 | fonts/archivo/vf/Archiv0-SemiBoldItalic-tosf-ts1.vf 2020/12/30 | 588 | fonts/archivo/vf/Archiv0-SemiBoldItalic-tlf-ts1.vf 2020/12/30 | 588 | fonts/archivo/vf/Archiv0-SemiBoldItalic-osf-ts1.vf @@ -107,7 +911,6 @@ 2020/12/30 | 5836 | fonts/archivo/tfm/Archiv0-Regular-tlf-t1.tfm 2020/12/30 | 5836 | fonts/archivo/tfm/Archiv0-Regular-osf-t1.tfm 2020/12/30 | 5836 | fonts/archivo/tfm/Archiv0-Regular-lf-t1.tfm -2020/12/30 | 582486 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma 2020/12/30 | 580 | fonts/archivo/vf/Archiv0-SemiBold-tlf-ts1.vf 2020/12/30 | 580 | fonts/archivo/vf/Archiv0-SemiBold-osf-ts1.vf 2020/12/30 | 580 | fonts/archivo/vf/Archiv0-SemiBold-lf-ts1.vf @@ -127,21 +930,10 @@ 2020/12/30 | 576 | fonts/archivo/vf/Archiv0-Bold-tlf-ts1.vf 2020/12/30 | 576 | fonts/archivo/vf/Archiv0-Bold-osf-ts1.vf 2020/12/30 | 576 | fonts/archivo/vf/Archiv0-Bold-lf-ts1.vf -2020/12/30 | 57436 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma 2020/12/30 | 5720 | systems/texlive/tlnet/archive/uninormalize.r57257.tar.xz -2020/12/30 | 57101 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma -2020/12/30 | 567838 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma 2020/12/30 | 566 | macros/latex/contrib/skeldoc/README.md -2020/12/30 | 56471 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma -2020/12/30 | 56363 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma 2020/12/30 | 56330 | macros/latex/contrib/xurl/doc/xurl.pdf -2020/12/30 | 56208 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma 2020/12/30 | 558292 | systems/texlive/tlnet/archive/biblatex-ieee.doc.r57256.tar.xz -2020/12/30 | 55790 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma -2020/12/30 | 554529 | systems/win32/miktex/tm/packages/files.csv.lzma -2020/12/30 | 554006 | systems/win32/miktex/tm/packages/next/files.csv.lzma -2020/12/30 | 55136 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma -2020/12/30 | 5500415 | systems/texlive/tlnet/install-tl-unx.tar.gz 2020/12/30 | 5400 | systems/texlive/tlnet/archive/biblatex-ieee.r57256.tar.xz 2020/12/30 | 5344 | fonts/archivo/tfm/Archiv0-MediumItalic-tosf-ly1.tfm 2020/12/30 | 5344 | fonts/archivo/tfm/Archiv0-MediumItalic-tlf-ly1.tfm @@ -151,24 +943,15 @@ 2020/12/30 | 5324 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tlf-ly1.tfm 2020/12/30 | 5324 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-osf-ly1.tfm 2020/12/30 | 5324 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-lf-ly1.tfm -2020/12/30 | 531711 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma 2020/12/30 | 5310 | macros/latex/contrib/xurl/doc/xurl.tex -2020/12/30 | 52462 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma 2020/12/30 | 5220 | fonts/archivo/tfm/Archiv0-BoldItalic-tosf-ly1.tfm 2020/12/30 | 5220 | fonts/archivo/tfm/Archiv0-BoldItalic-tlf-ly1.tfm 2020/12/30 | 5220 | fonts/archivo/tfm/Archiv0-BoldItalic-lf-ly1.tfm 2020/12/30 | 5216 | fonts/archivo/tfm/Archiv0-BoldItalic-osf-ly1.tfm -2020/12/30 | 52165 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma -2020/12/30 | 51768 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma -2020/12/30 | 51746 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma -2020/12/30 | 51381 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma -2020/12/30 | 51320 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma -2020/12/30 | 511888 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma 2020/12/30 | 5112 | fonts/archivo/tfm/Archiv0-Italic-tosf-ly1.tfm 2020/12/30 | 5112 | fonts/archivo/tfm/Archiv0-Italic-tlf-ly1.tfm 2020/12/30 | 5112 | fonts/archivo/tfm/Archiv0-Italic-lf-ly1.tfm 2020/12/30 | 5108 | fonts/archivo/tfm/Archiv0-Italic-osf-ly1.tfm -2020/12/30 | 50709 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma 2020/12/30 | 5036 | fonts/archivo/tfm/Archiv0-SemiBold-tosf-ly1.tfm 2020/12/30 | 5036 | fonts/archivo/tfm/Archiv0-SemiBold-tlf-ly1.tfm 2020/12/30 | 5036 | fonts/archivo/tfm/Archiv0-SemiBold-osf-ly1.tfm @@ -178,7 +961,6 @@ 2020/12/30 | 5036 | fonts/archivo/tfm/Archiv0-Medium-osf-ly1.tfm 2020/12/30 | 5036 | fonts/archivo/tfm/Archiv0-Medium-lf-ly1.tfm 2020/12/30 | 501064 | systems/texlive/tlnet/archive/jlreq.doc.r57255.tar.xz -2020/12/30 | 50032 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma 2020/12/30 | 4936 | fonts/archivo/tfm/Archiv0-Bold-tosf-ly1.tfm 2020/12/30 | 4936 | fonts/archivo/tfm/Archiv0-Bold-tlf-ly1.tfm 2020/12/30 | 4936 | fonts/archivo/tfm/Archiv0-Bold-osf-ly1.tfm @@ -187,78 +969,40 @@ 2020/12/30 | 4916 | fonts/archivo/tfm/Archiv0-Regular-tlf-ly1.tfm 2020/12/30 | 4916 | fonts/archivo/tfm/Archiv0-Regular-osf-ly1.tfm 2020/12/30 | 4916 | fonts/archivo/tfm/Archiv0-Regular-lf-ly1.tfm -2020/12/30 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 -2020/12/30 | 483101 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma -2020/12/30 | 47850 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma 2020/12/30 | 4774198 | biblio/bibtex/contrib/gost.zip -2020/12/30 | 475839 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma 2020/12/30 | 4707 | macros/latex/contrib/biblatex-contrib/biblatex-nature/biblatex-nature.tex -2020/12/30 | 46877 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma 2020/12/30 | 4662 | macros/latex/contrib/xurl/latex/xurl.sty -2020/12/30 | 460885 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma -2020/12/30 | 45843 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma -2020/12/30 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc -2020/12/30 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc -2020/12/30 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc -2020/12/30 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc -2020/12/30 | 45541 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma -2020/12/30 | 45199 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma +2020/12/30 | 43947 | macros/luatex/generic/lualibs/lualibs-util-str.lua 2020/12/30 | 4371 | fonts/archivo/doc/LICENSE.TXT -2020/12/30 | 43398 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma -2020/12/30 | 43151 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma -2020/12/30 | 43071 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma -2020/12/30 | 42942 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma 2020/12/30 | 427 | macros/latex/contrib/xurl/Changes -2020/12/30 | 42572 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma -2020/12/30 | 42287 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma 2020/12/30 | 416 | fonts/archivo/doc/Archivo-samples.tex -2020/12/30 | 41319 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma -2020/12/30 | 41009 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma 2020/12/30 | 4016 | macros/luatex/generic/luamplib/test-luamplib-latex.tex 2020/12/30 | 3968 | systems/texlive/tlnet/archive/puyotikz.r57254.tar.xz -2020/12/30 | 39566 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma -2020/12/30 | 39542 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma -2020/12/30 | 392500 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma -2020/12/30 | 388 | systems/texlive/tlnet/archive/texlive-docindex.r57250.tar.xz 2020/12/30 | 388952 | install/macros/latex/contrib/biblatex-contrib/biblatex-nature.tds.zip 2020/12/30 | 388324 | macros/latex/contrib/biblatex-contrib/biblatex-nature.zip 2020/12/30 | 3872 | macros/luatex/generic/luamplib/test-luamplib-plain.tex +2020/12/30 | 38703 | macros/luatex/generic/lualibs/lualibs-lpeg.lua 2020/12/30 | 383348 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008-customized.pdf 2020/12/30 | 3832 | biblio/bibtex/contrib/gost/source/gost.ins 2020/12/30 | 382545 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008-customized.pdf -2020/12/30 | 38038 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma 2020/12/30 | 379357 | macros/latex/contrib/biblatex-contrib/biblatex-nature/biblatex-nature.pdf 2020/12/30 | 376555 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008n.pdf 2020/12/30 | 375296 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008n.pdf 2020/12/30 | 375282 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008ns.pdf 2020/12/30 | 375170 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008ns.pdf 2020/12/30 | 372722 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2003.pdf -2020/12/30 | 37233 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma -2020/12/30 | 37233 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma 2020/12/30 | 371851 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2003.pdf 2020/12/30 | 371764 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008l.pdf 2020/12/30 | 371016 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008l.pdf 2020/12/30 | 369861 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008.pdf 2020/12/30 | 369224 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008.pdf -2020/12/30 | 36703 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma -2020/12/30 | 36596 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma 2020/12/30 | 3654 | info/latex2e-help-texinfo-fr/NEWS-fr -2020/12/30 | 35470 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma -2020/12/30 | 35038 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma -2020/12/30 | 343640 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma -2020/12/30 | 34194 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma -2020/12/30 | 33387 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma -2020/12/30 | 33143 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma -2020/12/30 | 330225 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma -2020/12/30 | 32597 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma +2020/12/30 | 32815 | macros/luatex/generic/lualibs/lualibs-util-tab.lua 2020/12/30 | 3199 | fonts/archivo/latex/TS1ArchivZero-TOsF.fd 2020/12/30 | 3199 | fonts/archivo/latex/OT1ArchivZero-TOsF.fd 2020/12/30 | 3199 | fonts/archivo/latex/LY1ArchivZero-TOsF.fd -2020/12/30 | 319753 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma -2020/12/30 | 31956 | systems/texlive/tlnet/archive/gost.source.r57251.tar.xz 2020/12/30 | 3178 | fonts/archivo/enc/a_owzwzj.enc 2020/12/30 | 3164 | fonts/archivo/latex/T1ArchivZero-TOsF.fd -2020/12/30 | 31551 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma 2020/12/30 | 3148 | fonts/archivo/latex/TS1ArchivZero-TLF.fd 2020/12/30 | 3148 | fonts/archivo/latex/TS1ArchivZero-OsF.fd 2020/12/30 | 3148 | fonts/archivo/latex/OT1ArchivZero-TLF.fd @@ -267,62 +1011,33 @@ 2020/12/30 | 3148 | fonts/archivo/latex/LY1ArchivZero-TLF.fd 2020/12/30 | 3148 | fonts/archivo/latex/LY1ArchivZero-Sup.fd 2020/12/30 | 3148 | fonts/archivo/latex/LY1ArchivZero-OsF.fd -2020/12/30 | 31392 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma -2020/12/30 | 31349 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma -2020/12/30 | 31249 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma 2020/12/30 | 3113 | fonts/archivo/latex/T1ArchivZero-TLF.fd 2020/12/30 | 3113 | fonts/archivo/latex/T1ArchivZero-Sup.fd 2020/12/30 | 3113 | fonts/archivo/latex/T1ArchivZero-OsF.fd 2020/12/30 | 3097 | fonts/archivo/latex/TS1ArchivZero-LF.fd 2020/12/30 | 3097 | fonts/archivo/latex/OT1ArchivZero-LF.fd 2020/12/30 | 3097 | fonts/archivo/latex/LY1ArchivZero-LF.fd -2020/12/30 | 309294 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma -2020/12/30 | 30889 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma 2020/12/30 | 3062 | fonts/archivo/latex/T1ArchivZero-LF.fd 2020/12/30 | 3031 | fonts/archivo/enc/a_fiyauo.enc 2020/12/30 | 3022 | fonts/archivo/enc/a_flfbvu.enc 2020/12/30 | 3020 | fonts/archivo/enc/a_24xxsv.enc -2020/12/30 | 29931 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma 2020/12/30 | 2990 | fonts/archivo/enc/a_utd4ik.enc 2020/12/30 | 2981 | fonts/archivo/enc/a_lwgukc.enc 2020/12/30 | 2979 | fonts/archivo/enc/a_mq36jn.enc -2020/12/30 | 295531 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma -2020/12/30 | 29410 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma -2020/12/30 | 29264 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma 2020/12/30 | 2918 | fonts/archivo/enc/a_ttjzpe.enc 2020/12/30 | 2909 | fonts/archivo/enc/a_7npxgm.enc 2020/12/30 | 2907 | fonts/archivo/enc/a_vgwtwr.enc 2020/12/30 | 2905 | fonts/archivo/enc/a_lzhlbi.enc -2020/12/30 | 28978 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma 2020/12/30 | 2864 | fonts/archivo/enc/a_vqpkf5.enc -2020/12/30 | 283901 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma -2020/12/30 | 28229 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma -2020/12/30 | 280109 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma -2020/12/30 | 27947 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma 2020/12/30 | 2792 | fonts/archivo/enc/a_5xld5w.enc 2020/12/30 | 2752 | macros/luatex/generic/luamplib/Makefile -2020/12/30 | 27212 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma -2020/12/30 | 27198 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma -2020/12/30 | 27195 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma -2020/12/30 | 27041 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma 2020/12/30 | 265270 | biblio/bibtex/contrib/gost/doc/examples/utf8/ugost2008s.pdf 2020/12/30 | 261913 | biblio/bibtex/contrib/gost/doc/examples/cp1251/gost2008s.pdf -2020/12/30 | 2616450 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma -2020/12/30 | 258691 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma 2020/12/30 | 2523 | fonts/archivo/latex/Archivo.sty -2020/12/30 | 25090 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma -2020/12/30 | 25015 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma -2020/12/30 | 250138 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma -2020/12/30 | 2495179 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma +2020/12/30 | 24683 | macros/luatex/generic/lualibs/lualibs-util-prs.lua 2020/12/30 | 2466841 | info/latex2e-help-texinfo-fr.zip -2020/12/30 | 243464 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma -2020/12/30 | 24270384 | systems/texlive/tlnet/install-tl.zip 2020/12/30 | 24040 | macros/latex/contrib/skeldoc/skeldoc.sty -2020/12/30 | 23866 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma -2020/12/30 | 23265 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma -2020/12/30 | 231839 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma 2020/12/30 | 226458 | macros/latex/contrib/skeldoc.zip -2020/12/30 | 2257520 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tosf-ot1.tfm 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tlf-ot1.tfm 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-osf-ot1.tfm @@ -331,26 +1046,19 @@ 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-MediumItalic-tlf-ot1.tfm 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-MediumItalic-osf-ot1.tfm 2020/12/30 | 2228 | fonts/archivo/tfm/Archiv0-MediumItalic-lf-ot1.tfm -2020/12/30 | 22020 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma +2020/12/30 | 21925004 | biblio/biber/binaries/Solaris_Intel/biber-x86_64-pc-solaris2.11.tar.xz 2020/12/30 | 218656 | systems/texlive/tlnet/archive/texlive-scripts.doc.r57250.tar.xz 2020/12/30 | 216738 | macros/latex/contrib/skeldoc/skeldoc.pdf -2020/12/30 | 212474 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma -2020/12/30 | 212397 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma -2020/12/30 | 21166 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma 2020/12/30 | 2112 | fonts/archivo/tfm/Archiv0-BoldItalic-tosf-ot1.tfm 2020/12/30 | 2112 | fonts/archivo/tfm/Archiv0-BoldItalic-tlf-ot1.tfm 2020/12/30 | 2112 | fonts/archivo/tfm/Archiv0-BoldItalic-osf-ot1.tfm 2020/12/30 | 2112 | fonts/archivo/tfm/Archiv0-BoldItalic-lf-ot1.tfm -2020/12/30 | 210605 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma 2020/12/30 | 2092 | fonts/archivo/tfm/Archiv0-Italic-tosf-ot1.tfm 2020/12/30 | 2092 | fonts/archivo/tfm/Archiv0-Italic-tlf-ot1.tfm 2020/12/30 | 2092 | fonts/archivo/tfm/Archiv0-Italic-lf-ot1.tfm 2020/12/30 | 2088 | fonts/archivo/tfm/Archiv0-Italic-osf-ot1.tfm -2020/12/30 | 207981 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma 2020/12/30 | 2056 | fonts/archivo/tfm/Archiv0-SemiBold-osf-ot1.tfm 2020/12/30 | 2056 | fonts/archivo/tfm/Archiv0-Medium-osf-ot1.tfm -2020/12/30 | 205396 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma -2020/12/30 | 205354 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma 2020/12/30 | 2052 | fonts/archivo/tfm/Archiv0-SemiBold-tosf-ot1.tfm 2020/12/30 | 2052 | fonts/archivo/tfm/Archiv0-SemiBold-tlf-ot1.tfm 2020/12/30 | 2052 | fonts/archivo/tfm/Archiv0-SemiBold-lf-ot1.tfm @@ -358,32 +1066,18 @@ 2020/12/30 | 2052 | fonts/archivo/tfm/Archiv0-Medium-tlf-ot1.tfm 2020/12/30 | 2052 | fonts/archivo/tfm/Archiv0-Medium-lf-ot1.tfm 2020/12/30 | 20483 | fonts/archivo/map/ArchivZero.map -2020/12/30 | 202753 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma -2020/12/30 | 20132 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma 2020/12/30 | 201144 | systems/texlive/tlnet/archive/puyotikz.doc.r57254.tar.xz 2020/12/30 | 1996 | macros/luatex/generic/luamplib/README -2020/12/30 | 199606 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma -2020/12/30 | 1985831 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma -2020/12/30 | 198078 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma 2020/12/30 | 196220 | install/macros/luatex/generic/luamplib.tds.zip -2020/12/30 | 195611 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma 2020/12/30 | 1952 | fonts/archivo/tfm/Archiv0-Bold-osf-ot1.tfm 2020/12/30 | 1948 | fonts/archivo/tfm/Archiv0-Bold-tosf-ot1.tfm 2020/12/30 | 1948 | fonts/archivo/tfm/Archiv0-Bold-tlf-ot1.tfm 2020/12/30 | 1948 | fonts/archivo/tfm/Archiv0-Bold-lf-ot1.tfm 2020/12/30 | 1944 | fonts/archivo/tfm/Archiv0-Regular-osf-ot1.tfm -2020/12/30 | 194178 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma 2020/12/30 | 1940 | fonts/archivo/tfm/Archiv0-Regular-tosf-ot1.tfm 2020/12/30 | 1940 | fonts/archivo/tfm/Archiv0-Regular-tlf-ot1.tfm 2020/12/30 | 1940 | fonts/archivo/tfm/Archiv0-Regular-lf-ot1.tfm -2020/12/30 | 19387534 | systems/texlive/tlnet/install-tl-windows.exe -2020/12/30 | 193530 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma 2020/12/30 | 182036 | macros/luatex/generic/luamplib.zip -2020/12/30 | 180253 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma -2020/12/30 | 18009 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma -2020/12/30 | 179341 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma -2020/12/30 | 17876 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma -2020/12/30 | 1766840 | systems/texlive/tlnet/archive/gost.doc.r57251.tar.xz 2020/12/30 | 1732 | fonts/archivo/vf/Archiv0-SemiBoldItalic-tosf-t1.vf 2020/12/30 | 1732 | fonts/archivo/vf/Archiv0-SemiBoldItalic-tlf-t1.vf 2020/12/30 | 1732 | fonts/archivo/vf/Archiv0-SemiBoldItalic-osf-t1.vf @@ -395,7 +1089,6 @@ 2020/12/30 | 1728 | fonts/archivo/vf/Archiv0-BoldItalic-tosf-t1.vf 2020/12/30 | 1728 | fonts/archivo/vf/Archiv0-BoldItalic-tlf-t1.vf 2020/12/30 | 1728 | fonts/archivo/vf/Archiv0-BoldItalic-osf-t1.vf -2020/12/30 | 17272 | systems/texlive/tlnet/archive/gost.r57251.tar.xz 2020/12/30 | 1724 | fonts/archivo/vf/Archiv0-SemiBold-tosf-t1.vf 2020/12/30 | 1724 | fonts/archivo/vf/Archiv0-SemiBold-tlf-t1.vf 2020/12/30 | 1724 | fonts/archivo/vf/Archiv0-SemiBold-osf-t1.vf @@ -443,7 +1136,6 @@ 2020/12/30 | 1708 | fonts/archivo/vf/Archiv0-Italic-tlf-ly1.vf 2020/12/30 | 1708 | fonts/archivo/vf/Archiv0-Italic-osf-ly1.vf 2020/12/30 | 1708 | fonts/archivo/vf/Archiv0-BoldItalic-lf-ly1.vf -2020/12/30 | 170828 | systems/texlive/tlnet/archive/texlive-docindex.doc.r57250.tar.xz 2020/12/30 | 1704 | fonts/archivo/vf/Archiv0-Medium-lf-ly1.vf 2020/12/30 | 1704 | fonts/archivo/vf/Archiv0-Italic-lf-ly1.vf 2020/12/30 | 1704 | fonts/archivo/vf/Archiv0-Bold-tosf-ly1.vf @@ -452,7 +1144,6 @@ 2020/12/30 | 1704 | fonts/archivo/vf/Archiv0-Bold-lf-ly1.vf 2020/12/30 | 1700 | fonts/archivo/vf/Archiv0-SemiBoldItalic-sup-t1.vf 2020/12/30 | 1700 | fonts/archivo/vf/Archiv0-MediumItalic-sup-t1.vf -2020/12/30 | 1699737 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma 2020/12/30 | 1696 | fonts/archivo/vf/Archiv0-SemiBold-sup-t1.vf 2020/12/30 | 1696 | fonts/archivo/vf/Archiv0-BoldItalic-sup-t1.vf 2020/12/30 | 1692 | fonts/archivo/vf/Archiv0-Regular-sup-t1.vf @@ -464,12 +1155,10 @@ 2020/12/30 | 1684 | fonts/archivo/vf/Archiv0-MediumItalic-sup-ly1.vf 2020/12/30 | 1680 | fonts/archivo/vf/Archiv0-SemiBold-sup-ly1.vf 2020/12/30 | 1680 | fonts/archivo/vf/Archiv0-BoldItalic-sup-ly1.vf -2020/12/30 | 16783174 | systems/texlive/tlnet/tlpkg/texlive.tlpdb 2020/12/30 | 1676 | fonts/archivo/vf/Archiv0-Regular-sup-ly1.vf 2020/12/30 | 1676 | fonts/archivo/vf/Archiv0-Medium-sup-ly1.vf 2020/12/30 | 1676 | fonts/archivo/vf/Archiv0-Italic-sup-ly1.vf 2020/12/30 | 1676 | fonts/archivo/vf/Archiv0-Bold-sup-ly1.vf -2020/12/30 | 165760 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma 2020/12/30 | 1644 | fonts/archivo/tfm/Archiv0-MediumItalic-sup-ly1.tfm 2020/12/30 | 1640 | fonts/archivo/tfm/Archiv0-MediumItalic-tosf-ly1--base.tfm 2020/12/30 | 1640 | fonts/archivo/tfm/Archiv0-MediumItalic-tlf-ly1--base.tfm @@ -477,9 +1166,6 @@ 2020/12/30 | 1640 | fonts/archivo/tfm/Archiv0-MediumItalic-lf-ly1--base.tfm 2020/12/30 | 1636 | fonts/archivo/tfm/Archiv0-MediumItalic-osf-ly1--base.tfm 2020/12/30 | 1628 | fonts/archivo/tfm/Archiv0-MediumItalic-sup-t1.tfm -2020/12/30 | 16233 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma -2020/12/30 | 162262 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma -2020/12/30 | 16216 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma 2020/12/30 | 1620 | fonts/archivo/tfm/Archiv0-MediumItalic-sup-t1--base.tfm 2020/12/30 | 1616 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tosf-ly1--base.tfm 2020/12/30 | 1616 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tlf-ly1--base.tfm @@ -497,7 +1183,6 @@ 2020/12/30 | 1600 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-sup-t1--base.tfm 2020/12/30 | 1600 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-osf-t1--base.tfm 2020/12/30 | 1600 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-lf-t1--base.tfm -2020/12/30 | 159925 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma 2020/12/30 | 1596 | fonts/archivo/tfm/Archiv0-Italic-sup-ly1.tfm 2020/12/30 | 1592 | fonts/archivo/tfm/Archiv0-Italic-tosf-ly1--base.tfm 2020/12/30 | 1592 | fonts/archivo/tfm/Archiv0-Italic-tlf-ly1--base.tfm @@ -523,16 +1208,11 @@ 2020/12/30 | 1552 | fonts/archivo/tfm/Archiv0-BoldItalic-tlf-t1--base.tfm 2020/12/30 | 1552 | fonts/archivo/tfm/Archiv0-BoldItalic-lf-t1--base.tfm 2020/12/30 | 1548 | fonts/archivo/tfm/Archiv0-BoldItalic-osf-t1--base.tfm -2020/12/30 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512 -2020/12/30 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512 -2020/12/30 | 152375 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma -2020/12/30 | 152157 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma 2020/12/30 | 149233 | macros/luatex/generic/luamplib/luamplib.pdf 2020/12/30 | 1476 | fonts/archivo/tfm/Archiv0-Medium-tosf-ly1--base.tfm 2020/12/30 | 1476 | fonts/archivo/tfm/Archiv0-Medium-tlf-ly1--base.tfm 2020/12/30 | 1476 | fonts/archivo/tfm/Archiv0-Medium-osf-ly1--base.tfm 2020/12/30 | 1476 | fonts/archivo/tfm/Archiv0-Medium-lf-ly1--base.tfm -2020/12/30 | 147334 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma 2020/12/30 | 1472 | fonts/archivo/tfm/Archiv0-SemiBold-tosf-ly1--base.tfm 2020/12/30 | 1472 | fonts/archivo/tfm/Archiv0-SemiBold-tlf-ly1--base.tfm 2020/12/30 | 1472 | fonts/archivo/tfm/Archiv0-SemiBold-osf-ly1--base.tfm @@ -550,12 +1230,9 @@ 2020/12/30 | 1464 | fonts/archivo/tfm/Archiv0-Medium-sup-ly1.tfm 2020/12/30 | 1460 | fonts/archivo/tfm/Archiv0-SemiBold-sup-ly1.tfm 2020/12/30 | 1460 | fonts/archivo/tfm/Archiv0-Medium-sup-ly1--base.tfm -2020/12/30 | 145 | systems/texlive/tlnet/install-tl.zip.sha512 2020/12/30 | 1456 | fonts/archivo/tfm/Archiv0-SemiBold-sup-t1--base.tfm 2020/12/30 | 1456 | fonts/archivo/tfm/Archiv0-SemiBold-sup-ly1--base.tfm 2020/12/30 | 1456 | fonts/archivo/tfm/Archiv0-Medium-sup-t1--base.tfm -2020/12/30 | 145309 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma -2020/12/30 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 2020/12/30 | 1448 | fonts/archivo/tfm/Archiv0-Bold-tosf-ly1--base.tfm 2020/12/30 | 1448 | fonts/archivo/tfm/Archiv0-Bold-tlf-ly1--base.tfm 2020/12/30 | 1448 | fonts/archivo/tfm/Archiv0-Bold-osf-ly1--base.tfm @@ -565,7 +1242,6 @@ 2020/12/30 | 1436 | fonts/archivo/tfm/Archiv0-Regular-osf-ly1--base.tfm 2020/12/30 | 1436 | fonts/archivo/tfm/Archiv0-Regular-lf-ly1--base.tfm 2020/12/30 | 1436 | fonts/archivo/tfm/Archiv0-Bold-sup-ly1.tfm -2020/12/30 | 14358 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma 2020/12/30 | 1432 | fonts/archivo/tfm/Archiv0-Bold-sup-ly1--base.tfm 2020/12/30 | 1428 | fonts/archivo/tfm/Archiv0-Regular-sup-ly1.tfm 2020/12/30 | 1424 | fonts/archivo/tfm/Archiv0-Regular-sup-ly1--base.tfm @@ -580,7 +1256,6 @@ 2020/12/30 | 1416 | fonts/archivo/tfm/Archiv0-Regular-sup-t1.tfm 2020/12/30 | 1416 | fonts/archivo/tfm/Archiv0-Regular-osf-t1--base.tfm 2020/12/30 | 1416 | fonts/archivo/tfm/Archiv0-Regular-lf-t1--base.tfm -2020/12/30 | 1416387 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma 2020/12/30 | 1412 | fonts/archivo/tfm/Archiv0-Bold-sup-t1--base.tfm 2020/12/30 | 1408 | fonts/archivo/tfm/Archiv0-Regular-sup-t1--base.tfm 2020/12/30 | 1408 | fonts/archivo/tfm/Archiv0-MediumItalic-tosf-ts1.tfm @@ -608,7 +1283,6 @@ 2020/12/30 | 1380 | fonts/archivo/tfm/Archiv0-Italic-tlf-ts1--base.tfm 2020/12/30 | 1380 | fonts/archivo/tfm/Archiv0-Italic-osf-ts1--base.tfm 2020/12/30 | 1380 | fonts/archivo/tfm/Archiv0-Italic-lf-ts1--base.tfm -2020/12/30 | 1380784 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma 2020/12/30 | 1376 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tosf-ts1--base.tfm 2020/12/30 | 1376 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-tlf-ts1--base.tfm 2020/12/30 | 1376 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-osf-ts1--base.tfm @@ -622,8 +1296,6 @@ 2020/12/30 | 1348 | fonts/archivo/tfm/Archiv0-Medium-osf-ts1.tfm 2020/12/30 | 1348 | fonts/archivo/tfm/Archiv0-Medium-lf-ts1.tfm 2020/12/30 | 134796 | systems/texlive/tlnet/archive/jlreq.r57255.tar.xz -2020/12/30 | 13475 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma -2020/12/30 | 134712 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma 2020/12/30 | 1344 | fonts/archivo/tfm/Archiv0-Regular-tosf-ts1.tfm 2020/12/30 | 1344 | fonts/archivo/tfm/Archiv0-Regular-tlf-ts1.tfm 2020/12/30 | 1344 | fonts/archivo/tfm/Archiv0-Regular-osf-ts1.tfm @@ -647,7 +1319,6 @@ 2020/12/30 | 1320 | fonts/archivo/tfm/Archiv0-Regular-tlf-ts1--base.tfm 2020/12/30 | 1320 | fonts/archivo/tfm/Archiv0-Regular-osf-ts1--base.tfm 2020/12/30 | 1320 | fonts/archivo/tfm/Archiv0-Regular-lf-ts1--base.tfm -2020/12/30 | 131918 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma 2020/12/30 | 131796 | fonts/archivo/opentype/Archiv0-MediumItalic.otf 2020/12/30 | 1316 | fonts/archivo/tfm/Archiv0-SemiBold-tosf-ts1--base.tfm 2020/12/30 | 1316 | fonts/archivo/tfm/Archiv0-SemiBold-tlf-ts1--base.tfm @@ -658,52 +1329,34 @@ 2020/12/30 | 1312 | fonts/archivo/tfm/Archiv0-Bold-tlf-ts1--base.tfm 2020/12/30 | 1312 | fonts/archivo/tfm/Archiv0-Bold-osf-ts1--base.tfm 2020/12/30 | 1312 | fonts/archivo/tfm/Archiv0-Bold-lf-ts1--base.tfm -2020/12/30 | 131229 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma 2020/12/30 | 130552 | fonts/archivo/opentype/Archiv0-Italic.otf -2020/12/30 | 1304654 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma 2020/12/30 | 12926 | biblio/bibtex/contrib/gost/README.md -2020/12/30 | 1282238 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma 2020/12/30 | 125956 | fonts/archivo/opentype/Archiv0-SemiBold.otf -2020/12/30 | 1253449 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma 2020/12/30 | 123768 | fonts/archivo/opentype/Archiv0-Medium.otf 2020/12/30 | 12345 | macros/latex/contrib/biblatex-contrib/biblatex-nature/biblatex-nature.bib -2020/12/30 | 1233774 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma -2020/12/30 | 1233455 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma 2020/12/30 | 122872 | fonts/archivo/opentype/Archiv0-Bold.otf 2020/12/30 | 122492 | fonts/archivo/opentype/Archiv0-Regular.otf 2020/12/30 | 1206870 | info/latex2e-help-texinfo-fr/latex2e-fr.pdf -2020/12/30 | 120281 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma 2020/12/30 | 1196 | fonts/archivo/tfm/Archiv0-MediumItalic-sup-ot1.tfm +2020/12/30 | 119604689 | macros/context/latest/cont-tmf.zip 2020/12/30 | 1188 | fonts/archivo/tfm/Archiv0-SemiBoldItalic-sup-ot1.tfm -2020/12/30 | 1171089 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma -2020/12/30 | 116824 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma 2020/12/30 | 1163273 | info/latex2e-help-texinfo-fr/latex2e-fr.xml 2020/12/30 | 1160 | fonts/archivo/tfm/Archiv0-Italic-sup-ot1.tfm 2020/12/30 | 1156 | fonts/archivo/tfm/Archiv0-BoldItalic-sup-ot1.tfm -2020/12/30 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini -2020/12/30 | 1151438 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma -2020/12/30 | 1151428 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma -2020/12/30 | 114807 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma -2020/12/30 | 113773 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma -2020/12/30 | 109178 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma -2020/12/30 | 1078478 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma 2020/12/30 | 1075 | macros/latex/contrib/skeldoc/LICENSE 2020/12/30 | 10709 | info/latex2e-help-texinfo-fr/README +2020/12/30 | 10588256 | systems/win32/w32tex/ptex-w32.tar.xz 2020/12/30 | 1050597 | fonts/archivo.zip -2020/12/30 | 104831 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma 2020/12/30 | 1044 | fonts/archivo/tfm/Archiv0-Medium-sup-ot1.tfm 2020/12/30 | 1040 | fonts/archivo/tfm/Archiv0-SemiBold-sup-ot1.tfm 2020/12/30 | 103464 | systems/texlive/tlnet/archive/oswald.doc.r57253.tar.xz -2020/12/30 | 103387 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma -2020/12/30 | 101755 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma 2020/12/30 | 1008 | fonts/archivo/tfm/Archiv0-Regular-sup-ot1.tfm 2020/12/30 | 1008 | fonts/archivo/tfm/Archiv0-Bold-sup-ot1.tfm +2020/12/29 | 9412 | macros/luatex/generic/lualibs/lualibs-util-sta.lua 2020/12/29 | 9096 | graphics/pgf/contrib/puyotikz/puyotikz.tex -2020/12/29 | 87572488 | systems/win32/w32tex/pgfcontrib.tar.xz 2020/12/29 | 863 | graphics/pgf/contrib/puyotikz/README.md 2020/12/29 | 81770 | macros/latex/contrib/nomencl/sample03.pdf 2020/12/29 | 80170 | macros/latex/contrib/nomencl/sample02.pdf -2020/12/29 | 759079 | systems/win32/w32tex/ChangeLog 2020/12/29 | 7337 | macros/latex/contrib/biblatex-contrib/biblatex-ieee/biblatex-ieee.tex 2020/12/29 | 70337 | macros/luatex/latex/uninormalize.zip 2020/12/29 | 692726 | install/macros/latex/contrib/biblatex-contrib/biblatex-ieee.tds.zip @@ -712,15 +1365,16 @@ 2020/12/29 | 6596 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl 2020/12/29 | 637 | macros/latex/contrib/biblatex-contrib/biblatex-ieee/README.md 2020/12/29 | 635314 | macros/latex/contrib/nomencl.zip -2020/12/29 | 6236 | systems/texlive/tlnet/archive/collection-latexextra.r57248.tar.xz 2020/12/29 | 58662516 | systems/win32/w32tex/TLARM64W/tl-arm64-windows.zip 2020/12/29 | 580995 | language/japanese/jlreq.zip 2020/12/29 | 5227 | language/japanese/jlreq/README.md +2020/12/29 | 5115 | macros/luatex/generic/lualibs/lualibs-gzip.lua 2020/12/29 | 4844 | systems/texlive/tlnet/archive/expkv-def.r57246.tar.xz 2020/12/29 | 48313 | macros/latex/contrib/nomencl/sample04.pdf 2020/12/29 | 460 | biblio/bibtex/contrib/gost/doc/examples/utf8/bib/ex77.bib 2020/12/29 | 460 | biblio/bibtex/contrib/gost/doc/examples/cp1251/bib/ex77.bib 2020/12/29 | 4364 | systems/texlive/tlnet/archive/froufrou.source.r57248.tar.xz +2020/12/29 | 41758 | macros/luatex/generic/lualibs/lualibs-table.lua 2020/12/29 | 41600 | language/japanese/jlreq/README-ja.md 2020/12/29 | 4084 | macros/latex/contrib/biblatex-contrib/biblatex-ieee/ieee.cbx 2020/12/29 | 404044 | systems/texlive/tlnet/archive/expkv.doc.r57247.tar.xz @@ -735,6 +1389,7 @@ 2020/12/29 | 3446916 | systems/win32/w32tex/win64/luajittex-exp-w64.tar.xz 2020/12/29 | 34412 | macros/latex/contrib/nomencl/sample01.pdf 2020/12/29 | 342134 | macros/latex/contrib/nomencl/nomencl.pdf +2020/12/29 | 3414 | macros/luatex/generic/lualibs/lualibs-md5.lua 2020/12/29 | 34043 | macros/latex/contrib/nomencl/sample05.pdf 2020/12/29 | 33904064 | systems/win32/w32tex/ltxpkgs.tar.xz 2020/12/29 | 3124116 | systems/win32/w32tex/win64/luatex-w64.tar.xz @@ -746,6 +1401,7 @@ 2020/12/29 | 2372 | systems/texlive/tlnet/archive/froufrou.r57248.tar.xz 2020/12/29 | 2265 | macros/latex/contrib/biblatex-contrib/biblatex-ieee/magyar-ieee.lbx 2020/12/29 | 2252 | macros/latex/contrib/biblatex-contrib/biblatex-ieee/ieee-alphabetic.cbx +2020/12/29 | 22175 | macros/luatex/generic/lualibs/lualibs-file.lua 2020/12/29 | 20636 | systems/texlive/tlnet/archive/expkv.source.r57247.tar.xz 2020/12/29 | 204727 | graphics/pgf/contrib/puyotikz.zip 2020/12/29 | 201230 | graphics/pgf/contrib/puyotikz/puyotikz.pdf @@ -759,6 +1415,7 @@ 2020/12/29 | 136756 | systems/texlive/tlnet/archive/circuitikz.r57245.tar.xz 2020/12/29 | 1270 | macros/latex/contrib/nomencl/README 2020/12/29 | 1219796 | systems/texlive/tlnet/archive/circuitikz.doc.r57245.tar.xz +2020/12/29 | 11829 | macros/luatex/generic/lualibs/lualibs-io.lua 2020/12/29 | 116684 | language/japanese/jlreq/jlreq.pdf 2020/12/29 | 1137032 | fonts/oswald.zip 2020/12/29 | 10934115 | install/language/japanese/jlreq.tds.zip @@ -789,6 +1446,8 @@ 2020/12/28 | 305384 | systems/texlive/tlnet/archive/ptex-fontmaps.source.r57239.tar.xz 2020/12/28 | 2668 | macros/luatex/latex/uninormalize/README.md 2020/12/28 | 24040 | systems/texlive/tlnet/archive/cslatex.source.r57242.tar.xz +2020/12/28 | 22779316 | biblio/biber/binaries/FreeBSD/biber-amd64-freebsd.tar.xz +2020/12/28 | 20866528 | biblio/biber/binaries/FreeBSD/biber-i386-freebsd.tar.xz 2020/12/28 | 2059 | macros/latex/contrib/froufrou/froufrou.ins 2020/12/28 | 19000 | systems/texlive/tlnet/archive/cslatex.doc.r57242.tar.xz 2020/12/28 | 1853 | macros/luatex/latex/uninormalize/unicode-normalize-names.lua @@ -800,7 +1459,6 @@ 2020/12/28 | 14108 | systems/texlive/tlnet/archive/bookcover.source.r57241.tar.xz 2020/12/28 | 12744 | systems/texlive/tlnet/archive/cslatex.r57242.tar.xz 2020/12/28 | 1263 | macros/generic/expkv-def/README.md -2020/12/28 | 119601928 | macros/context/latest/cont-tmf.zip 2020/12/28 | 10748 | macros/luatex/latex/uninormalize/unicode-normalization.lua 2020/12/28 | 10717352 | systems/texlive/tlnet/archive/pgf.doc.r57240.tar.xz 2020/12/28 | 1020 | fonts/oswald/README @@ -1707,7 +2365,6 @@ 2020/12/27 | 1865 | graphics/pgf/base/source/CirclePlacer_script.h 2020/12/27 | 1864 | graphics/pgf/base/lua/graphdrawing/pgf/gd/examples/BindingToASCII.lua 2020/12/27 | 1864 | fonts/ptex-fontmaps/maps/moga-mobo/otf-up-moga-mobo.map -2020/12/27 | 1860 | systems/texlive/tlnet/archive/collection-fontsextra.r57232.tar.xz 2020/12/27 | 1859 | fonts/ptex-fontmaps/maps/sourcehan-otc/otf-ko-sourcehan-otc.map 2020/12/27 | 18579596 | systems/win32/w32tex/luatex-dev-w32.tar.xz 2020/12/27 | 184 | fonts/ptex-fontmaps/maps/ms-osx/uptex-sc-ms-osx.map @@ -1724,7 +2381,9 @@ 2020/12/27 | 182 | fonts/ptex-fontmaps/maps/fandol/uptex-sc-fandol.map 2020/12/27 | 18230 | fonts/ptex-fontmaps/kanji-config-updmap.tex 2020/12/27 | 1817 | fonts/ptex-fontmaps/maps/noto/otf-ko-noto.map +2020/12/27 | 18132544 | biblio/biber/binaries/Cygwin/biber-cygwin64.tar.gz 2020/12/27 | 18032 | graphics/pgf/base/doc/licenses/gnu-public-license-2.txt +2020/12/27 | 18007106 | biblio/biber/binaries/Cygwin/biber-cygwin32.tar.gz 2020/12/27 | 1790 | graphics/pgf/base/lua/graphdrawing/pgf/gd/layered/node_positioning.lua 2020/12/27 | 1783 | fonts/ptex-fontmaps/maps/sourcehan-otc/otf-sc-sourcehan-otc.map 2020/12/27 | 1778 | graphics/pgf/base/lua/graphdrawing/pgf/gd/planar/LinkedList.lua @@ -2194,39 +2853,3 @@ 2020/12/25 | 1068 | macros/latex/contrib/acro/examples/acro.example.texsx-505891.tex 2020/12/25 | 105785 | macros/luatex/generic/chinese-jfm/doc.pdf 2020/12/25 | 101133 | macros/latex/contrib/acro/acro-manual.tex -2020/12/24 | 94628 | systems/texlive/tlnet/archive/latexmk.r57213.tar.xz -2020/12/24 | 89 | macros/latex/contrib/lwarp/lwarp_baseline_marker.png -2020/12/24 | 873268 | systems/texlive/tlnet/archive/latex2e-help-texinfo-spanish.doc.r57213.tar.xz -2020/12/24 | 856 | systems/texlive/tlnet/archive/latexmk.source.r57213.tar.xz -2020/12/24 | 719 | macros/latex/contrib/lwarp/lwarp_baseline_marker.eps -2020/12/24 | 712 | systems/texlive/tlnet/archive/latex2e-help-texinfo-spanish.r57213.tar.xz -2020/12/24 | 708 | systems/texlive/tlnet/archive/latex2e-help-texinfo.r57213.tar.xz -2020/12/24 | 6608 | systems/texlive/tlnet/archive/ut-thesis.source.r57213.tar.xz -2020/12/24 | 6518676 | systems/texlive/tlnet/archive/inter.r57213.tar.xz -2020/12/24 | 56576 | systems/texlive/tlnet/archive/arvo.doc.r57213.tar.xz -2020/12/24 | 55896 | systems/texlive/tlnet/archive/inter.doc.r57213.tar.xz -2020/12/24 | 52763124 | systems/win32/w32tex/w32tex-src.tar.xz -2020/12/24 | 513436 | systems/texlive/tlnet/archive/biblatex-swiss-legal.doc.r57213.tar.xz -2020/12/24 | 511088 | systems/texlive/tlnet/archive/oup-authoring-template.doc.r57213.tar.xz -2020/12/24 | 473740 | systems/texlive/tlnet/archive/latexmk.doc.r57213.tar.xz -2020/12/24 | 4120 | systems/texlive/tlnet/archive/swfigure.r57213.tar.xz -2020/12/24 | 4023304 | install/macros/latex/contrib/lwarp.tds.zip -2020/12/24 | 3468792 | macros/latex/contrib/lwarp.zip -2020/12/24 | 31747 | macros/latex/contrib/lwarp/lwarp.ins -2020/12/24 | 3023923 | macros/latex/contrib/lwarp/lwarp.pdf -2020/12/24 | 301996 | systems/texlive/tlnet/archive/oldstandard.doc.r57213.tar.xz -2020/12/24 | 2947 | macros/latex/contrib/lwarp/lwarp_tutorial.txt -2020/12/24 | 29001 | macros/latex/contrib/lwarp/lwarpmk.lua -2020/12/24 | 2616566 | macros/latex/contrib/lwarp/lwarp.dtx -2020/12/24 | 2544 | systems/texlive/tlnet/archive/ut-thesis.r57213.tar.xz -2020/12/24 | 21506 | macros/latex/contrib/bithesis/bithesis.dtx -2020/12/24 | 20900 | systems/texlive/tlnet/archive/swfigure.source.r57213.tar.xz -2020/12/24 | 18148 | systems/texlive/tlnet/archive/biblatex-swiss-legal.r57213.tar.xz -2020/12/24 | 1725896 | systems/texlive/tlnet/archive/latex2e-help-texinfo.doc.r57213.tar.xz -2020/12/24 | 1702320 | systems/texlive/tlnet/archive/oldstandard.r57213.tar.xz -2020/12/24 | 1624 | macros/latex/contrib/lwarp/README.txt -2020/12/24 | 1547640 | systems/texlive/tlnet/archive/swfigure.doc.r57213.tar.xz -2020/12/24 | 15128 | systems/texlive/tlnet/archive/oup-authoring-template.r57213.tar.xz -2020/12/24 | 116940 | systems/texlive/tlnet/archive/ut-thesis.doc.r57213.tar.xz -2020/12/24 | 1064 | macros/luatex/generic/chinese-jfm/LICENSE -2020/12/24 | 105664 | systems/texlive/tlnet/archive/arvo.r57213.tar.xz diff --git a/biblio/biber/documentation/Changes b/biblio/biber/documentation/Changes index d5a443be10..8ef324874d 100644 --- a/biblio/biber/documentation/Changes +++ b/biblio/biber/documentation/Changes @@ -1,5 +1,12 @@ Revision history for Biber +2.16 (2020-12) + * Better support for Unicode on Windows (10 1803+) with the + --winunicode option + * Option "output_macro_fields" no longer does anything as macro + fields are auto-detected. + * New options "output_no_macrodefs" and "output_all_macrodefs" control + BibTeX macros (@STRING) output for bibtex format output. 2.15 (2020-08) * Added --output-legacy-dates and --output-field-replace options to aid in outputting legacy bibtex format in tool and non-tool mode diff --git a/biblio/biber/documentation/biber.pdf b/biblio/biber/documentation/biber.pdf index f41453790d..f0c2ee3e88 100644 Binary files a/biblio/biber/documentation/biber.pdf and b/biblio/biber/documentation/biber.pdf differ diff --git a/macros/latex/base/README.md b/macros/latex/base/README.md index d566ca97ce..7c6328be6d 100644 --- a/macros/latex/base/README.md +++ b/macros/latex/base/README.md @@ -1,7 +1,7 @@ The LaTeX kernel ================ -Release 2020-10-01 patch level 2 +Release 2020-10-01 patch level 3 Overview -------- diff --git a/macros/latex/base/alltt.pdf b/macros/latex/base/alltt.pdf index dce36a436c..5cb6410fa1 100644 Binary files a/macros/latex/base/alltt.pdf and b/macros/latex/base/alltt.pdf differ diff --git a/macros/latex/base/cfgguide.pdf b/macros/latex/base/cfgguide.pdf index 2f9e6e9974..c0cb3f3c6f 100644 Binary files a/macros/latex/base/cfgguide.pdf and b/macros/latex/base/cfgguide.pdf differ diff --git a/macros/latex/base/changes.txt b/macros/latex/base/changes.txt index 29f3d2937f..cc8d59b61b 100644 --- a/macros/latex/base/changes.txt +++ b/macros/latex/base/changes.txt @@ -10,6 +10,78 @@ are not part of the distribution. All changes above are only part of the development branch for the next release. ================================================================================ +######################### +# 2020-10-01 PL 3 Release +######################### + +2020-12-18 Phelype Oleinik + + * lthooks.dtx: + Moved 'top-level' code label at the very end of hooks. + - In reverse hooks, 'top-level' goes at the beginning. + - 'top-level' cannot be used as a label outside of the top-level. + - The label for the 'top-level' cannot be changed. + - Simplified internal managing of default label. + Renamed \DeclareDefaultHookLabel to \SetDefaultHookLabel (the old name + will be kept until the next release). + Provide \PushDefaultHookLabel and \PopDefaultHookLabel. + Fixed a small bug in \ShowHook and \LogHook. + + * ltclass.dtx: + Remove \@expl@@@hook@curr@name@push@@n from \@pushfilename to + follow changes to lthooks.dtx. + +2020-12-10 Frank Mittelbach + + * ltfssbas.dtx (subsection{Macros for the user}): + Drop ``m'' if the series value is a member of a fixed list + and issue warning if doing it (gh/453) + +2020-11-24 Frank Mittelbach + + * latexrelease.ins: + reorder module loading to match the order used + in the format to correctly resolve dependencies (gh/434) + + * ltexpl.dtx (subsection{Loader}): + Load xparse in latexrelease if necessary and add missing + IncludeInRelease guards (gh/434) + + * ltdefns.dtx, ltfilehook.dtx, lthooks.dtx, ltxshipout.dtx: + Add rollback support for forward case (gh/434) + +2020-11-20 Phelype Oleinik + + * ltclass.dtx: + Remove file path from \@currname and use only \@currname to identify + a package internally (gh/422). + Add \@currpath and (temporarily) \@kernel@currpathstack. + In \ProvidesPackage check the argument with \strcmp instead of \ifx. + In case of substitution, copy the option list to the requested package. + + * ltfilehook.dtx: + Keep path in the replacement file (#2) in \declare@file@substitution. + In case of a replacement, pass the actually loaded file to \@addtofilelist. + Explicitly clear replacement flag after using it. + +2020-11-17 Frank Mittelbach + + * fntguide.tex: + Updated documentation of virtual shapes \updefault and \ulcdefault + +2020-11-09 Frank Mittelbach + + * ltmath.dtx: + \negmedspace and \negthickspace have been only in amsmath, + so we need to undefine for rollback because amsmath used + \newcommand back then (gh/423) + +2020-11-09 Frank Mittelbach + + * ltclass.dtx (section{Package/class rollback mechanism}): + Change help text for suspicous rollback, because the package may have + existed then --- there is just no rollback data (gh/423) + ######################### # 2020-10-01 PL 2 Release ######################### diff --git a/macros/latex/base/classes.pdf b/macros/latex/base/classes.pdf index b0be55c53f..05b9379ef4 100644 Binary files a/macros/latex/base/classes.pdf and b/macros/latex/base/classes.pdf differ diff --git a/macros/latex/base/clsguide.pdf b/macros/latex/base/clsguide.pdf index 1a7e752cc3..c5d32dda9f 100644 Binary files a/macros/latex/base/clsguide.pdf and b/macros/latex/base/clsguide.pdf differ diff --git a/macros/latex/base/cmfonts.pdf b/macros/latex/base/cmfonts.pdf index c3502760ce..fe8f0083f6 100644 Binary files a/macros/latex/base/cmfonts.pdf and b/macros/latex/base/cmfonts.pdf differ diff --git a/macros/latex/base/cyrguide.pdf b/macros/latex/base/cyrguide.pdf index 1331bbc54f..6fa40a338b 100644 Binary files a/macros/latex/base/cyrguide.pdf and b/macros/latex/base/cyrguide.pdf differ diff --git a/macros/latex/base/doc.pdf b/macros/latex/base/doc.pdf index dcb78001b3..5feed95398 100644 Binary files a/macros/latex/base/doc.pdf and b/macros/latex/base/doc.pdf differ diff --git a/macros/latex/base/docstrip.pdf b/macros/latex/base/docstrip.pdf index aeda25af00..2e31d253a1 100644 Binary files a/macros/latex/base/docstrip.pdf and b/macros/latex/base/docstrip.pdf differ diff --git a/macros/latex/base/encguide.pdf b/macros/latex/base/encguide.pdf index 286a167553..249493684e 100644 Binary files a/macros/latex/base/encguide.pdf and b/macros/latex/base/encguide.pdf differ diff --git a/macros/latex/base/exscale.pdf b/macros/latex/base/exscale.pdf index 8d33cdefab..339a4d161a 100644 Binary files a/macros/latex/base/exscale.pdf and b/macros/latex/base/exscale.pdf differ diff --git a/macros/latex/base/fix-cm.pdf b/macros/latex/base/fix-cm.pdf index 07ff74d687..f39aca2525 100644 Binary files a/macros/latex/base/fix-cm.pdf and b/macros/latex/base/fix-cm.pdf differ diff --git a/macros/latex/base/fntguide.pdf b/macros/latex/base/fntguide.pdf index b3824b59a1..97c8a844f7 100644 Binary files a/macros/latex/base/fntguide.pdf and b/macros/latex/base/fntguide.pdf differ diff --git a/macros/latex/base/fntguide.tex b/macros/latex/base/fntguide.tex index b6576a0237..7e0928c51b 100644 --- a/macros/latex/base/fntguide.tex +++ b/macros/latex/base/fntguide.tex @@ -42,7 +42,7 @@ newer NFSS features of 2020}\\ All rights reserved.} -\date{July 2020} +\date{November 2020} \begin{document} @@ -340,22 +340,25 @@ box warning, for example: \end{verbatim} The author commands for fonts set the five attributes: \begin{center} + \hspace*{-1em}% \begin{tabular}{rcl} \emph{Author command} & \emph{Attribute} & \emph{Value in} |article| \emph{class} \\ |\textnormal{..}| or |\normalfont| & family & |cmr| \\ + & series & |m| \\ + & shape & |n| \\[1pt] |\textrm{..}| or |\rmfamily| & family & |cmr| \\ |\textsf{..}| or |\sffamily| & family & |cmss| \\ |\texttt{..}| or |\ttfamily| & family & |cmtt| \\ |\textmd{..}| or |\mdseries| & series & |m| \\ - |\textbf{..}| or |\bfseries| & series & |bx| \\ - |\textup{..}| or |\upshape| & shape & |n| \\ + |\textbf{..}| or |\bfseries| & series & |bx| \\[1pt] |\textit{..}| or |\itshape| & shape & |it| \\ |\textsl{..}| or |\slshape| & shape & |sl| \\ |\textsc{..}| or |\scshape| & shape & |sc| \\ |\textssc{..}| or |\sscshape| & shape & |ssc| \\ |\textsw{..}| or |\swshape| & shape & |sw| \\ - |\textulc{..}| or |\ulcshape| & shape & |ulc| \\ + |\textulc{..}| or |\ulcshape| & shape & |ulc| (virtual) $\to$ |n|, |it|, |sl| or |ssc| \\ + |\textup{..}| or |\upshape| & shape & |up| (virtual) $\to$ |n| or |sc| \\[1pt] |\tiny| & size & |5pt| \\ |\scriptsize| & size & |7pt| \\ |\footnotesize| & size & |8pt| \\ @@ -520,8 +523,9 @@ and the |ssub| size function, see Section~\ref{sec:sizefunct}. The shapes selected by |\textit|, |\itshape|, |\textsl|, |\slshape|, |\textsc|, |\scshape|, |\textssc|, |\sscshape|, |\textsw|, |\swshape|, |\textulc|, |\ulcshape|, |\textup| and |\upshape|. By default these are -|it|, |sl|, |sc|, |ssc|, |sw|, |ulc| and |n|. |ulc| is special here -since it is a virtual one; it doesn't exist as a real shape. The +|it|, |sl|, |sc|, |ssc|, |sw|, |ulc| and |up|. Note that |ulc| and |up| are special here +because they are virtual shapes; they don't exist as real shape values. Instead they alter +the existing shape value based on rules, i.e., the result depends on context. The respective macros |\textulc| or |\ulcshape| change small capitals back to upper/lower case but will not change the font with respect to italics, slanted or swash. |\upshape| or |\textup| in contrast will diff --git a/macros/latex/base/graphpap.pdf b/macros/latex/base/graphpap.pdf index 8ebd4c91d3..8cad84bb4c 100644 Binary files a/macros/latex/base/graphpap.pdf and b/macros/latex/base/graphpap.pdf differ diff --git a/macros/latex/base/ifthen.pdf b/macros/latex/base/ifthen.pdf index 6218e4883a..be2ea9f956 100644 Binary files a/macros/latex/base/ifthen.pdf and b/macros/latex/base/ifthen.pdf differ diff --git a/macros/latex/base/inputenc.pdf b/macros/latex/base/inputenc.pdf index 0ee0cdd0ff..4c06af39d5 100644 Binary files a/macros/latex/base/inputenc.pdf and b/macros/latex/base/inputenc.pdf differ diff --git a/macros/latex/base/latexchanges.pdf b/macros/latex/base/latexchanges.pdf index d78a1e3b5a..97fcc3330b 100644 Binary files a/macros/latex/base/latexchanges.pdf and b/macros/latex/base/latexchanges.pdf differ diff --git a/macros/latex/base/latexrelease.ins b/macros/latex/base/latexrelease.ins index 99af17e8fb..ffc92374c3 100644 --- a/macros/latex/base/latexrelease.ins +++ b/macros/latex/base/latexrelease.ins @@ -81,11 +81,16 @@ extension .ins) which are part of the distribution. %\keepsilent \usedir{tex/latex/base} +% the order should match the order in the format in case there are dependencies +% (something defined in one module and used in another) + \generateFile{latexrelease.sty}{t}{% \from{ltclass.dtx} {latexreleasefirst,tracerollback}% \from{ltvers.dtx} {latexrelease}% \from{latexrelease.dtx}{latexrelease}% \from{ltdirchk.dtx} {latexrelease}% + \from{ltplain.dtx} {latexrelease}% + \from{ltluatex.dtx} {latexrelease}% empty \from{ltexpl.dtx} {latexrelease}% empty \from{ltdefns.dtx} {latexrelease}% \from{lthooks.dtx} {latexrelease}% empty % L3 layer module @@ -93,42 +98,39 @@ extension .ins) which are part of the distribution. \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty \from{ltpar.dtx} {latexrelease}% empty + \from{ltspace.dtx} {latexrelease}% + \from{ltlogos.dtx} {latexrelease}% empty + \from{ltfiles.dtx} {latexrelease}% + \from{ltoutenc.dtx} {latexrelease}% + \from{ltcounts.dtx} {latexrelease}% + \from{ltlength.dtx} {latexrelease}% + \from{ltfssbas.dtx} {latexrelease}% + \from{ltfssaxes.dtx} {latexrelease}% + \from{ltfsstrc.dtx} {latexrelease}% + \from{ltfssdcl.dtx} {latexrelease}% + \from{ltfssini.dtx} {latexrelease}% + \from{fontdef.dtx} {latexrelease}% (covering fontmath and fonttext) + \from{ltfntcmd.dtx} {latexrelease}% empty + \from{lttextcomp.dtx} {latexrelease}% + \from{ltpageno.dtx} {latexrelease}% empty + \from{ltxref.dtx} {latexrelease}% empty + \from{ltmiscen.dtx} {latexrelease}% + \from{ltmath.dtx} {latexrelease}% \from{ltlists.dtx} {latexrelease}% empty \from{ltboxes.dtx} {latexrelease}% \from{lttab.dtx} {latexrelease}% empty - \from{ltmath.dtx} {latexrelease}% \from{ltpictur.dtx} {latexrelease}% \from{ltthm.dtx} {latexrelease}% empty \from{ltsect.dtx} {latexrelease}% empty - \from{ltfiles.dtx} {latexrelease}% - \from{ltoutenc.dtx} {latexrelease}% - \from{ltcounts.dtx} {latexrelease}% - \from{ltlength.dtx} {latexrelease}% \from{ltfloat.dtx} {latexrelease}% \from{ltidxglo.dtx} {latexrelease}% empty \from{ltbibl.dtx} {latexrelease}% empty \from{ltpage.dtx} {latexrelease}% empty + \from{ltclass.dtx} {latexrelease,tracerollback}% \from{ltfilehook.dtx} {latexrelease}% empty % L3 layer module \from{ltshipout.dtx} {latexrelease}% empty % L3 layer module \from{ltoutput.dtx} {latexrelease}% - \from{ltclass.dtx} {latexrelease,tracerollback}% - \from{ltspace.dtx} {latexrelease}% - \from{ltlogos.dtx} {latexrelease}% empty - \from{ltplain.dtx} {latexrelease}% - \from{ltfssdcl.dtx} {latexrelease}% - \from{ltfssini.dtx} {latexrelease}% - \from{fontdef.dtx} {latexrelease}% (covering fontmath and fonttext) - \from{ltfntcmd.dtx} {latexrelease}% empty - \from{lttextcomp.dtx} {latexrelease}% - \from{ltfssbas.dtx} {latexrelease}% - \from{ltfssaxes.dtx} {latexrelease}% - \from{ltfsstrc.dtx} {latexrelease}% - \from{ltfsscmp.dtx} {latexrelease}% - \from{ltpageno.dtx} {latexrelease}% empty - \from{ltxref.dtx} {latexrelease}% empty - \from{ltmiscen.dtx} {latexrelease}% - \from{ltluatex.dtx} {latexrelease}% - \from{ltexpl.dtx} {latexrelease}% + \from{ltfsscmp.dtx} {latexrelease}% only in latexrelease! \from{ltfinal.dtx} {latexrelease}% } diff --git a/macros/latex/base/latexrelease.pdf b/macros/latex/base/latexrelease.pdf index f458d1a97c..d619076782 100644 Binary files a/macros/latex/base/latexrelease.pdf and b/macros/latex/base/latexrelease.pdf differ diff --git a/macros/latex/base/latexsym.pdf b/macros/latex/base/latexsym.pdf index 88db5ce701..436ea23f3a 100644 Binary files a/macros/latex/base/latexsym.pdf and b/macros/latex/base/latexsym.pdf differ diff --git a/macros/latex/base/lb2.pdf b/macros/latex/base/lb2.pdf index 4885ef5646..7d989cb0a0 100644 Binary files a/macros/latex/base/lb2.pdf and b/macros/latex/base/lb2.pdf differ diff --git a/macros/latex/base/letter.pdf b/macros/latex/base/letter.pdf index 85986ca947..104f1157e2 100644 Binary files a/macros/latex/base/letter.pdf and b/macros/latex/base/letter.pdf differ diff --git a/macros/latex/base/lgc2.pdf b/macros/latex/base/lgc2.pdf index bfed998126..f900bfefb3 100644 Binary files a/macros/latex/base/lgc2.pdf and b/macros/latex/base/lgc2.pdf differ diff --git a/macros/latex/base/lppl.pdf b/macros/latex/base/lppl.pdf index 18c3995534..20a630928c 100644 Binary files a/macros/latex/base/lppl.pdf and b/macros/latex/base/lppl.pdf differ diff --git a/macros/latex/base/ltclass.dtx b/macros/latex/base/ltclass.dtx index b639ae9410..c62136c309 100644 --- a/macros/latex/base/ltclass.dtx +++ b/macros/latex/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/10/18 v1.3t LaTeX Kernel (Class & Package Interface)] + [2020/12/17 v1.3v LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -524,6 +524,27 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@currpath} +% Path to the current file if explicitly given. +% \changes{v1.3u}{2020/11/20}{Macro added} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +% +%\IncludeInRelease{2020/10/01}{\@currpath}% +% {Add \@currpath}% +\let\@currpath\@empty +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@currpath}% +% {Add \@currpath}% +%\let\@currpath\@undefined +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@currname} % Name of current package or option. % \begin{macrocode} @@ -562,6 +583,7 @@ % \changes{v1.3l}{2020/06/05}{Added \cs{@expl@push@filename@@} % and \cs{@expl@push@filename@aux@@}} % \changes{v1.3s}{2020/10/08}{Added missing 2020/02/02 \cs{IncludeInRelease}} +% \changes{v1.3v}{2020/12/14}{Removed \cs{@expl@@@hook@curr@name@push@@n}} % \begin{macrocode} % %<*2ekernel|latexrelease> @@ -578,13 +600,22 @@ % here, e.g., \cs{@expl@push@filename@@} needs cleanup and (and % should probably not have this name either). % \begin{macrocode} - \@expl@@@hook@curr@name@push@@n{}% \@expl@push@filename@@ \xdef\@currnamestack{% {\@currname}% {\@currext}% {\the\catcode`\@}% \@currnamestack}% +% \end{macrocode} +% Temporarily add a stack for \cs{@currpath} here. This should be +% integrated in the main file stack eventually, but other packages +% rely on \cs{@currnamestack} having three elements per file, so that +% isn't a trivial change. The prefix \cs{@kernel@...} hopefully +% discourages people from using it. +% \begin{macrocode} + \xdef\@kernel@currpathstack{% + {\@currpath}% + \@kernel@currpathstack}% \@expl@push@filename@aux@@} %\EndIncludeInRelease % \end{macrocode} @@ -632,6 +663,10 @@ % {Add \@expl@pop@filename@@}% \def\@popfilename{\@expl@@@hook@curr@name@pop@@ \expandafter\@p@pfilename\@currnamestack\@nil +% \end{macrocode} +% Same for popping: +% \begin{macrocode} + \expandafter\@p@pfilepath\@kernel@currpathstack\@nil \@expl@pop@filename@@} %\EndIncludeInRelease % @@ -672,6 +707,36 @@ % \end{macro} % \end{macro} % +% +% \begin{macro}{\@kernel@currpathstack} +% Path to the current file if explicitly given. The auxiliary is +% needed here to insert a \cs{@empty} to prevent the loss of braces. +% \changes{v1.3u}{2020/11/20}{Macro added} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +% +%\IncludeInRelease{2020/10/01}{\@kernel@currpathstack}% +% {Add \@kernel@currpathstack}% +\gdef\@kernel@currpathstack{} +\def\@p@pfilepath#1{% + \gdef\@currpath{#1}\@p@pfilepath@aux\@empty} +\def\@p@pfilepath@aux#1\@nil{% + \xdef\@kernel@currpathstack{#1}} +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@kernel@currpathstack}% +% {Add \@kernel@currpathstack}% +%\let\@kernel@currpathstack\@undefined +%\let\@p@pfilepath\@undefined +%\let\@p@pfilepath@aux\@undefined +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{\@ptionlist} % Returns the option list of the file. % \begin{macrocode} @@ -915,15 +980,42 @@ % \changes{v0.3c}{1994/03/12} % {use \cs{@gtempa}} % \begin{macrocode} +% +%\IncludeInRelease{2020/10/01}% +% {\ProvidesPackage}{Check name with \strcmp}% +%<*2ekernel|latexrelease> \def\ProvidesPackage#1{% \xdef\@gtempa{#1}% - \ifx\@gtempa\@currname\else +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Use string comparison instead of \cs{ifx}} +% Here \cs{@currpath} is explicitly added to the file name to report +% when a package or class is loaded using an explicit path. Loading +% using a path in the argument is supported but not encouraged. +% \begin{macrocode} + \@expandtwoargs\@expl@str@if@eq@@nnTF + {\@gtempa}{\@currpath\@currname}{}{% \@latex@warning@no@line{You have requested - \@cls@pkg\space`\@currname',\MessageBreak + \@cls@pkg\space`\@currpath\@currname',\MessageBreak but the \@cls@pkg\space provides `#1'}% - \fi + }% \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%] \@onlypreamble\ProvidesPackage +% +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}% +% {\ProvidesPackage}{Undo: check name with \strcmp}% +%\def\ProvidesPackage#1{% +% \xdef\@gtempa{#1}% +% \ifx\@gtempa\@currname\else +% \@latex@warning@no@line{You have requested +% \@cls@pkg\space`\@currname',\MessageBreak +% but the \@cls@pkg\space provides `#1'}% +% \fi +% \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%] +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1007,9 +1099,18 @@ % % \begin{macro}{\ProvidesClass} % Like |\ProvidesPackage|, but for classes. +% This needs a dummy \pkg{latexrelease} block to copy the definition +% of \cs{ProvidesPackage} as it changes across releases. % \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}% +% {\ProvidesClass}{Track \ProvidesPackage}% +%<*2ekernel|latexrelease> \let\ProvidesClass\ProvidesPackage \@onlypreamble\ProvidesClass +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1075,10 +1176,18 @@ \@expl@@@filehook@set@curr@file@@nNN {\@expl@@@filehook@resolve@file@subst@@w #3.#1\@nil}% \reserved@a\reserved@b + \@expl@@@filehook@clear@replacement@flag@@ \expandafter\xdef\csname opt@\reserved@a\endcsname{% \@ifundefined{opt@\reserved@a}\@empty {\csname opt@\reserved@a\endcsname,}% - \zap@space#2 \@empty}} + \zap@space#2 \@empty}% +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Copy option list to the requested package.} +% \begin{macrocode} + \expandafter\let + \csname opt@#3.#1\expandafter\endcsname + \csname opt@\reserved@a\endcsname} % %\EndIncludeInRelease % @@ -1719,8 +1828,38 @@ %\IncludeInRelease{2020/10/01}% % {\@onefilewithoptions}{Hooks and unused options issue}% \def\@onefilewithoptions#1[#2][#3]#4{% +% \end{macrocode} +% We have to sanitise file names, so that something like +% \begin{verbatim} +% \usepackage{some/local/path/array} +% \usepackage{array} +% \end{verbatim} +% won't load \file{array.sty} twice. It is remotely possible that +% those are two different files, but as a matter of principles, we +% will consider that the base file name uniquely identifies a +% package, regardless of where it lives. This assumption already +% holds for file hooks, for example, which address the hook to a file +% by its base name only. +% +% We'll use \cs{@expl@@@filehook@set@curr@file@@nNN} to parse the +% file name and return the \meta{path} and \meta{base+ext} in +% separate token lists. Further ahead, most operations use +% \cs{@currname} which doesn't have a path attached to it; only few +% actions prepend \cs{@currpath} to \cs{@currname} (namely loading, +% as we have to respect the given path). +% +% A file substituiton isn't followed just yet because at this point +% we are parsing user input, so the file is still what the user +% asked for, and not the file actually loaded. +% \begin{macrocode} + \@expl@@@filehook@set@curr@file@@nNN{#1.#4}\reserved@a\reserved@b + \edef\reserved@c{\def\noexpand\reserved@c####1% + \detokenize\expandafter{\expanded{.#4}}% + \noexpand\@nil{\def\noexpand\reserved@a{####1}}}\reserved@c + \expandafter\reserved@c\reserved@a\@nil \@pushfilename - \xdef\@currname{#1}% + \xdef\@currname{\string@makeletter\reserved@a}% + \xdef\@currpath{\ifx\reserved@b\@empty\else\reserved@b/\fi}% \global\let\@currext#4% % \end{macrocode} % The command \cs{ver@\meta{file}.\meta{ext}} is used to signal that @@ -1765,9 +1904,11 @@ % \end{macrocode} % First we take the \meta{name} and \meta{ext} given in the argument % and check if the file exists, and issue an error otherwise asking -% for a correction with \cs{@missingfileerror}. +% for a correction with \cs{@missingfileerror}. For checking if the +% file exists we use \cs{@currpath} (usually empty) before +% \cs{@currname}. % \begin{macrocode} - \IfFileExists{\@currname.\@currext}{}% + \IfFileExists{\@currpath\@currname.\@currext}{}% {\@missing@onefilewithoptions{#2}}% % \end{macrocode} % If \cs{@currname} is empty (the user replied to the ``Enter file @@ -1784,11 +1925,12 @@ % do the bookkeeping with \cs{@filehook@file@push} % then call \cs{set@curr@file} to set \cs{@curr@file} (and do any % required substitution), then actually load the class/package with -% \cs{load@onefile@withoptions}. +% \cs{load@onefile@withoptions}. \cs{set@curr@file} also needs the +% file path. % \begin{macrocode} \@disable@packageload@do{\@currname.\@currext}% {\@expl@@@filehook@file@push@@ - \set@curr@file{\@currname.\@currext}% + \set@curr@file{\@currpath\@currname.\@currext}% \@filehook@set@CurrentFile % \end{macrocode} % \changes{v1.3q}{2020/09/06} @@ -1812,10 +1954,15 @@ \expandafter\@swaptwoargs\expandafter {\expandafter{\@currpkg@reqd}}% {% < +% \end{macrocode} +% \cs{@currpkg@reqd} doesn't take a path because it is used later to +% assign \cs[no-index]{opt@...} and \cs[no-index]{ver@...}. +% \begin{macrocode} \edef\@currpkg@reqd{\@currname.\@currext}% \ifx\CurrentFile\CurrentFileUsed \else \filename@parse\@curr@file + \edef\@currpath{\string@makeletter\filename@area}% \edef\@currname{\string@makeletter\filename@base}% \edef\@currext{\string@makeletter\filename@ext}% \fi @@ -1864,11 +2011,13 @@ % \end{macro} % % \begin{macro}{\@missing@onefilewithoptions} -% Now the action taken when a file is not found. +% Now the action taken when a file is not found. Path must be +% included here as it eventually leads to a file lookup. % \begin{macrocode} \def\@missing@onefilewithoptions#1{% - \@missingfileerror\@currname\@currext - \xdef\@currname{\@missingfile@area\@missingfile@base}% + \@missingfileerror{\@currpath\@currname}\@currext + \global\let\@currpath\@missingfile@area + \global\let\@currname\@missingfile@base \global\let\@currext\@missingfile@ext} % \end{macrocode} % \end{macro} @@ -1887,6 +2036,13 @@ % \begin{macrocode} \def\reserved@a{% \@pass@ptions\@currext{#1}{\@currname}% +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Copy option list to the requested package.} +% \begin{macrocode} + \expandafter\let + \csname opt@\@currpkg@reqd\expandafter\endcsname + \csname opt@\@currname.\@currext\endcsname \global\expandafter \let\csname ver@\@currname.\@currext\endcsname\@empty % \end{macrocode} @@ -1912,11 +2068,12 @@ \fi % \end{macrocode} % Now actually load the file (at this point we are certain it exists, -% but use \cs{InputIfFileExists} so that file hooks are executed): +% but use \cs{InputIfFileExists} so that file hooks are executed). +% \cs{@currpath} is needed here too. % \begin{macrocode} - \InputIfFileExists{\@currpkg@reqd}{}% + \InputIfFileExists{\@currpath\@currpkg@reqd}{}% {\@latex@error - {The \@cls@pkg\space\@currpkg@reqd\space failed to load.}\@ehd}% + {The \@cls@pkg\space\@currpkg@reqd\space failed to load}\@ehd}% %----------------------------------------- % \end{macrocode} % In older versions of the code |\@unprocessedoptions| would @@ -3271,19 +3428,20 @@ % A similar error is given if global rollback date and min-date on % a specific package conflict with each other, but that case is % happens only once so it is inlined. +% \changes{v1.3u}{2020/11/09}{Change help text because the package may have +% existed then --- there is just no rollback data (gh/423).} % \begin{macrocode} \def\pkgcls@rollbackdate@error#1{% \@latex@error{Suspicious rollback date given}% - {The \@cls@pkg\space'\@currname' claims that it - came into existence on #1 which\MessageBreak + {The \@cls@pkg\space'\@currname' has no rollback data + before #1 which\MessageBreak is after your requested rollback date --- so - something is wrong here.\MessageBreak + something may be wrong here.\MessageBreak Continue and we use the earliest known release.}} % \end{macrocode} % \end{macro} % % -% % \begin{macro}{\DeclareCurrentRelease} % This declares the date (and possible name) of the current version % of a package or class. diff --git a/macros/latex/base/ltdefns.dtx b/macros/latex/base/ltdefns.dtx index 569c9db4df..920c1acde6 100644 --- a/macros/latex/base/ltdefns.dtx +++ b/macros/latex/base/ltdefns.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2020/09/25 v1.5n LaTeX Kernel (definition commands)] + [2020/11/25 v1.5o LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -385,8 +385,19 @@ % \begin{macro}{\@carcube} % |\@carcube T1 ... Tn\@nil| = |T1| |T2| |T3| , $n > 3$ % \changes{v1.5k}{2020/08/19}{Made \cs{long} for \cs{NewCommandCopy}} +% \changes{v1.5o}{2020/11/25}{Added missing latexrelease entry} % \begin{macrocode} +% +%\IncludeInRelease{2020/10/01}{\@carcube}{Make \@carcube long}% +%<*2ekernel|latexrelease> \long\def\@carcube#1#2#3#4\@nil{#1#2#3} +% +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@carcube}{Undo: Make \@carcube long}% +%\def\@carcube#1#2#3#4\@nil{#1#2#3} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/ltexpl.dtx b/macros/latex/base/ltexpl.dtx index 4100da79c2..7f9019ede3 100644 --- a/macros/latex/base/ltexpl.dtx +++ b/macros/latex/base/ltexpl.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2020/09/06 v1.2f LaTeX Kernel (expl3-dependent code)] + [2020/12/18 v1.2h LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -72,16 +72,45 @@ % {Define a local version of some \LaTeXe{} basic macros to support % package loading} % +% \begin{macro}{\@kernel@after@enddocument, +% \@kernel@after@enddocument@afterlastpage} +% These two kernel hooks are used by the shipout code. They are +% defined earlier here because the \pkg{lthooks} code adds material +% to them. +% \changes{v1.2h}{2020/12/18} +% {Define kernel \cs{enddocument} hooks early} +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% +\let\@kernel@after@enddocument\@empty +\let\@kernel@after@enddocument@afterlastpage\@empty +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% +%\let\@kernel@after@enddocument\@undefined +%\let\@kernel@after@enddocument@afterlastpage\@undefined +%\EndIncludeInRelease +% +% \end{macrocode} +% \end{macro} +% % First define some blank commands, so that in case something goes wrong while % loading \textsf{expl3}, we won't get strange \texttt{Undefined control % sequence} errors. % \begin{macrocode} -%<*2ekernel> +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\@expl@sys@load@backend@@}{Roll forward support}% \def\@expl@sys@load@backend@@{} \def\@expl@push@filename@@{} \def\@expl@push@filename@aux@@{} \def\@expl@pop@filename@@{} -% +%\EndIncludeInRelease +% % \end{macrocode} % % \changes{v1.2d}{2020/07/08} @@ -183,9 +212,20 @@ \errmessage{LaTeX requires expl3}% \batchmode \read -1 to \reserved@a % +% \end{macrocode} +% We do not support a roll forward across 2019. You need to start +% with 2019 if you want to get to 2020 or beyond. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} %<*latexrelease> - \@latex@error{LaTeX requires expl3}\@ehd - \@gobble + \@latex@warning@no@line + {You need a format that already contains a recent\MessageBreak + expl3 as part of the kernel, e.g. at least a kernel\MessageBreak + from 2019 to roll forward to that date!\MessageBreak + --- I'm giving up!\MessageBreak\MessageBreak + Note that manually loading the expl3 package\MessageBreak + from your distribution is not enough}% + \@@end % die % }% {% @@ -222,6 +262,36 @@ %\EndIncludeInRelease % \end{macrocode} % +% +% Starting with 2020-10 the kernel contains most of the +% \texttt{xparse} interfaces loaded above. These interfaces are +% later used to define various user command. However, if somebody +% with an earlier installation tries to roll forward (using a +% \texttt{latexrelease} package from a newer release) this will not +% work as the earlier kernel doesn't contain commands such as +% \cs{NewDocumentCommand}. +% +% We therefore add code into \texttt{latexrelease.sty} to load the +% \texttt{xparse} package of the current installation instead. this +% may not work if the installation is really old, but roll forward +% can't do miracles. +% +% If the kernel is 2020-10 or later \cs{NewDocumentCommand} is +% already known (whether or not you roll forward or back) so +% nothing happens, but if you start from am earlier kernel the +% \texttt{xparse} package gets loaded by \texttt{latexrelease}. +% \changes{v1.2g}{2020/11/24}{Load xparse in latexrelease if needed (gh/434)} +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}% +% {\NewDocumentCommand}{Emergency loading xparse}% +% +%\ifdefined\NewDocumentCommand \else +% \RequirePackage{xparse} +%\fi +% +%\EndIncludeInRelease +% \end{macrocode} +% % \subsection{Using expl3 code} % % In order to ease the implemantation of some new features in @@ -242,9 +312,6 @@ % if that \pkg{expl3} command is needed in places that are others % coded in \LaTeXe{} conventions. % -% \begin{macrocode} -\ExplSyntaxOn -% \end{macrocode} % % In this file, each release of LaTeX adds an \cs{IncludeInRelease} % block, in which the macros copied for that release were defined. @@ -259,8 +326,16 @@ % redefinitions. % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{expl3~2020-10-01}% -% {expl3~macros~added~for~the~2020-10-01~release}% +%\IncludeInRelease{2020/10/01}{\@expl@cs@to@str@@N}% +% {expl3 macros added for the 2020-10-01 release}% +% \end{macrocode} +% +% The expl3 activation needs to be inside the release guards as +% otherwise rolling forward is broken in old kernels that do not +% have expl3 loaded. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +\ExplSyntaxOn % \end{macrocode} % % \changes{v1.2e}{2020/08/19} @@ -290,21 +365,27 @@ % \end{macrocode} % % \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% +% Here we can't assume that expl3 is available. It will be if we +% roll back but if this code is executed rolling forward it needs +% to be pure 2e. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} %\EndIncludeInRelease -%\IncludeInRelease{0000/00/00}{expl3~2020-10-01}% -% {expl3~macros~added~for~the~2020-10-01~release}% -%\cs_undefine:N \@expl@cs@to@str@@N -%\cs_undefine:N \@expl@str@if@eq@@nnTF -%\cs_undefine:N \@expl@cs@prefix@spec@@N -%\cs_undefine:N \@expl@cs@argument@spec@@N -%\cs_undefine:N \@expl@cs@replacement@spec@@N -%\cs_undefine:N \@expl@str@map@function@@NN +%\IncludeInRelease{0000/00/00}{\@expl@cs@to@str@@N}% +% {expl3 macros added for the 2020-10-01 release}% +%\let \@expl@cs@to@str@@N \@undefined +%\let \@expl@str@if@eq@@nnTF \@undefined +%\let \@expl@cs@prefix@spec@@N \@undefined +%\let \@expl@cs@argument@spec@@N \@undefined +%\let \@expl@cs@replacement@spec@@N \@undefined +%\let \@expl@str@map@function@@NN \@undefined %\EndIncludeInRelease % % \end{macrocode} % -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} % % \Finale diff --git a/macros/latex/base/ltfilehook-code.pdf b/macros/latex/base/ltfilehook-code.pdf index e35be13efe..fcbf09fe98 100644 Binary files a/macros/latex/base/ltfilehook-code.pdf and b/macros/latex/base/ltfilehook-code.pdf differ diff --git a/macros/latex/base/ltfilehook-doc.pdf b/macros/latex/base/ltfilehook-doc.pdf index 7bd9392a4d..bf7f37f22b 100644 Binary files a/macros/latex/base/ltfilehook-doc.pdf and b/macros/latex/base/ltfilehook-doc.pdf differ diff --git a/macros/latex/base/ltfilehook.dtx b/macros/latex/base/ltfilehook.dtx index ecb499f347..c7ed13f041 100644 --- a/macros/latex/base/ltfilehook.dtx +++ b/macros/latex/base/ltfilehook.dtx @@ -31,8 +31,8 @@ %%% From File: ltfilehook.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v1.0c} -\providecommand\ltfilehookdate{2020/10/18} +\providecommand\ltfilehookversion{v1.0d} +\providecommand\ltfilehookdate{2020/11/24} % \end{macrocode} % %<*driver> @@ -615,6 +615,62 @@ % \begin{macrocode} % %\EndIncludeInRelease +% \end{macrocode} +% +% When rolling forward the following expl3 functions may not be defined. +% If we roll back the code does nothing. +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}% +% {\file_parse_full_name_apply:nN}{Roll forward help}% +% +%\ExplSyntaxOn +%\cs_if_exist:NF\file_parse_full_name_apply:nN +%{ +%\cs_new:Npn \file_parse_full_name_apply:nN #1 +% { +% \exp_args:Ne \__file_parse_full_name_auxi:nN +% { \__kernel_file_name_sanitize:n {#1} } +% } +%\cs_new:Npn \__file_parse_full_name_auxi:nN #1 +% { +% \__file_parse_full_name_area:nw { } #1 +% / \s__file_stop +% } +%\cs_new:Npn \__file_parse_full_name_area:nw #1 #2 / #3 \s__file_stop +% { +% \tl_if_empty:nTF {#3} +% { \__file_parse_full_name_base:nw { } #2 . \s__file_stop {#1} } +% { \__file_parse_full_name_area:nw { #1 / #2 } #3 \s__file_stop } +% } +%\cs_new:Npn \__file_parse_full_name_base:nw #1 #2 . #3 \s__file_stop +% { +% \tl_if_empty:nTF {#3} +% { +% \tl_if_empty:nTF {#1} +% { +% \tl_if_empty:nTF {#2} +% { \__file_parse_full_name_tidy:nnnN { } { } } +% { \__file_parse_full_name_tidy:nnnN { .#2 } { } } +% } +% { \__file_parse_full_name_tidy:nnnN {#1} { .#2 } } +% } +% { \__file_parse_full_name_base:nw { #1 . #2 } #3 \s__file_stop } +% } +%\cs_new:Npn \__file_parse_full_name_tidy:nnnN #1 #2 #3 #4 +% { +% \exp_args:Nee #4 +% { +% \str_if_eq:nnF {#3} { / } { \use_none:n } +% #3 \prg_do_nothing: +% } +% { \use_none:n #1 \prg_do_nothing: } +% {#2} +% } +%} +%\ExplSyntaxOff +% +%\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % @@ -643,6 +699,8 @@ % kernel we do this only now and not in \texttt{ltfiles}. % % \begin{macro}{\InputIfFileExists} +% \begin{macro}{\@input@file@exists@with@hooks} +% \begin{macro}{\unqu@tefilef@und} % \cs{InputIfFileExists} loads any file if it is available so we % have to add the hooks \texttt{file/before} and % \texttt{file/after} in the right places. If the file doesn't @@ -665,7 +723,7 @@ % If the file exists then \cs{CurrentFile} holds its name. But we % can't rely on that still being true after the file has been % processed. Thus for using the name in the file hooks we need to -% preserve the name and then restored it for the +% preserve the name and then restore it for the % \texttt{file/after/...} hook. % % The hook always refers to the file requested by the user. The hook @@ -683,33 +741,68 @@ % refer to the file by their name only. The path to the file is % returned in \cs{CurrentFilePath}. % \begin{macrocode} - \edef\reserved@a{\@filef@und + \edef\reserved@a{% \@expl@@@filehook@file@pop@assign@@nnnn {\CurrentFilePathUsed}% {\CurrentFileUsed}% {\CurrentFilePath}% - {\CurrentFile}}% + {\CurrentFile}% +% \end{macrocode} +% +% We pre-expand \cs{@filef@und} so that in case another file is +% loaded in the true branch of \cs{InputIfFileExists}, these don't +% change their value meanwhile. This isn't a worry with +% \cs[no-index]{CurrentFile...} because they are kept in a stack. +% +% \changes{v1.0d}{2020/11/20} +% {Move loading to \cs{@input@file@exists@with@hooks} and expand +% \cs{@filef@und} to avoid getting the wrong file name in the case of +% a substitution.} +% \begin{macrocode} + \noexpand\@input@file@exists@with@hooks{\@filef@und}}% \expandafter\@swaptwoargs\expandafter {\reserved@a}% - {% - #2% - \@addtofilelist{#1}% - \UseHook{file/before}% + {#2}% + \@expl@@@filehook@file@pop@@ + }% +} +% \end{macrocode} +% +% Before adding to the file list we need to make all (letter) characters +% catcode~11, because several packages use constructions like +% \begin{verbatim} +% \filename@parse{} +% \ifx\filename@ext\@clsextension +% ... +% \fi +% \end{verbatim} +% and that doesn't work if \cs{filename@ext} is \cs{detokenize}d. +% Making \cs{@clsextension} a string doesn't help much because some +% packages define their own \cs[no-index]{@someextension} with +% normal catcodes. This is not entirely correct because packages loaded +% (somehow) with catcode~12 alphabetic tokens (say, as the result of +% a \cs{string} or \cs{detokenize} command, or from a \TeX{} string like +% \cs{jobname}) will have these character tokens incorrectly turned into +% letter tokens. This however is rare, so we'll go for the all-letters +% approach (grepping the packages in \TeX{} Live didn't bring up any +% obvious candidate for breaking with this catcode change). +% \begin{macrocode} +\def\@input@file@exists@with@hooks#1{% + \edef\reserved@a{\unqu@tefilef@und#1\@nil}% + \@addtofilelist{\string@makeletter\reserved@a}% + \UseHook{file/before}% % \end{macrocode} % The current file name is available in \cs{CurrentFile} so we use % that in the specific hook. % \begin{macrocode} - \UseHook{file/before/\CurrentFile}% - \@@input - }% + \UseHook{file/before/\CurrentFile}% + \@@input #1% <- trailing space comes from \@filef@und % \end{macrocode} % And it is restored here so we can use it once more. % \begin{macrocode} - \UseHook{file/after/\CurrentFile}% - \UseHook{file/after}% - \@expl@@@filehook@file@pop@@ - }% -} + \UseHook{file/after/\CurrentFile}% + \UseHook{file/after}} +\def\unqu@tefilef@und"#1" \@nil{#1} %\EndIncludeInRelease % % \end{macrocode} @@ -737,6 +830,8 @@ % {% % \expandafter\@swaptwoargs\expandafter % {\@filef@und}{#2\@addtofilelist{#1}\@@input}}} +%\let\@input@file@exists@with@hooks\@undefined +%\let\unqu@tefilef@und\@undefined %\EndIncludeInRelease % \end{macrocode} % @@ -746,10 +841,14 @@ %\long\def \InputIfFileExists#1#2{% % \IfFileExists{#1}% % {#2\@addtofilelist{#1}\@@input \@filef@und}} +%\let\@input@file@exists@with@hooks\@undefined +%\let\unqu@tefilef@und\@undefined %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % % @@ -772,8 +871,8 @@ % % % \begin{macro}{\@@_subst_add:nn,\@@_subst_remove:n, -% \@@_subst_file_normalize:n,\@@_subst_empty_name_chk:NN} -% \cs{@@_substitution_lthooadd:nn} declares a file substitution by +% \@@_subst_file_normalize:Nn,\@@_subst_empty_name_chk:NN} +% \cs{@@_subst_add:nn} declares a file substitution by % doing a (global) definition of the form % |\def|\cs{@file-subst@\meta{file}}|{|\meta{replacement}|}|. % The file names are properly sanitised, and normalized with the same @@ -787,8 +886,12 @@ \group_begin: \cs_set:cpx { } { \exp_not:o { \cs:w\cs_end: } } \int_set:Nn \tex_escapechar:D { -1 } - \cs_gset:cpx { @file-subst@ \@@_subst_file_normalize:n {#1} } - { \@@_subst_file_normalize:n {#2} } + \cs_gset:cpx + { + @file-subst@ + \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1} + } + { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn {#2} } \group_end: } \cs_new_protected:Npn \@@_subst_remove:n #1 @@ -796,14 +899,18 @@ \group_begin: \cs_set:cpx { } { \exp_not:o { \cs:w\cs_end: } } \int_set:Nn \tex_escapechar:D { -1 } - \cs_undefine:c { @file-subst@ \@@_subst_file_normalize:n {#1} } + \cs_undefine:c + { + @file-subst@ + \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1} + } \group_end: } -\cs_new:Npn \@@_subst_file_normalize:n #1 +\cs_new:Npn \@@_subst_file_normalize:Nn #1 #2 { \exp_after:wN \@@_subst_empty_name_chk:NN \cs:w \exp_after:wN \cs_end: - \cs:w \@@_file_parse_full_name:nN {#1} \use_ii_iii:nnn \cs_end: + \cs:w \@@_file_parse_full_name:nN {#2} #1 \cs_end: } \cs_new:Npn \@@_subst_empty_name_chk:NN #1 #2 { \if_meaning:w #1 #2 .tex \else: \token_to_str:N #2 \fi: } @@ -929,6 +1036,7 @@ \if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file@reqd \fi}% {\if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file \fi \global\let\@curr@file@reqd\@curr@file}% + \@expl@@@filehook@clear@replacement@flag@@ \endgroup} % %\EndIncludeInRelease @@ -1079,18 +1187,25 @@ % % \begin{macro}{flag @@_file_replaced} % \begin{macro}{\@@_if_file_replaced:TF} +% \begin{macro}{\@@_clear_replacement_flag:} % Since the file replacement is done expandably in a \cs{csname}, use % a flag to remember if a substitution happened. We use this in % \cs{set@curr@file} to short-circuit some of it in case no % substitution happened (by far the most common case, so it's worth -% optimising). +% optimising). The flag raised during the file substitution algorithm +% must be explicitly cleared after the \cs{@@_if_file_replaced:TF} +% conditional is no longer needed, otherwise further uses of +% \cs{@@_if_file_replaced:TF} will wrongly return true. % \begin{macrocode} \flag_new:n { @@_file_replaced } \cs_new:Npn \@@_if_file_replaced:TF #1 #2 - { \flag_if_raised:nTF { @@_file_replaced } {#1} {#2} } + { \flag_if_raised:nTF { @@_file_replaced } {#1} {#2} } +\cs_new_protected:Npn \@@_clear_replacement_flag: + { \flag_clear:n { @@_file_replaced } } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@@_file_subst_begin:nnn} % First off, start by checking if the current file ($\meta{name} + @@ -1343,7 +1458,12 @@ \cs_new_eq:NN \@expl@@@filehook@if@file@replaced@@TF \__filehook_if_file_replaced:TF % \end{macrocode} -% +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@clear@replacement@flag@@ + \__filehook_clear_replacement_flag: +% \end{macrocode} +% % \begin{macrocode} \cs_new_eq:NN \@expl@@@filehook@drop@extension@@N \__filehook_drop_extension:N diff --git a/macros/latex/base/ltfssaxes.dtx b/macros/latex/base/ltfssaxes.dtx index d8e4286b78..a66a26cd39 100644 --- a/macros/latex/base/ltfssaxes.dtx +++ b/macros/latex/base/ltfssaxes.dtx @@ -836,7 +836,7 @@ % condensed series, etc.). We do this in all branches above because a user % might have written %\begin{verbatim} -\DeclareFontSeriesChangeRule {m}{sc}{msc}{mc} +% \DeclareFontSeriesChangeRule {m}{sc}{msc}{mc} %\end{verbatim} % instead of using \texttt{sc} and \texttt{c} as needed in the % \texttt{.fd} file. diff --git a/macros/latex/base/ltfssbas.dtx b/macros/latex/base/ltfssbas.dtx index 4a6afca3ac..30f500b6e4 100644 --- a/macros/latex/base/ltfssbas.dtx +++ b/macros/latex/base/ltfssbas.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2020/02/27 v3.2g LaTeX Kernel (NFSS Basic Macros)] + [2020/12/10 v3.2h LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -891,12 +891,31 @@ % series and shape which is not desired if we intend to use an % explicit font shape! % \changes{v3.2e}{2019/12/17}{Don't call \cs{fontseries} or \cs{fontshape}} +% \changes{v3.2h}{2020/12/10}{Drop ``m'' if the series value is a member +% of a fixed list and issue warning if doing it (gh/453)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/02/02}% +% {\usefont}{Drop m in usefont}% \DeclareRobustCommand\usefont[4]{\fontencoding{#1}% \edef\f@family{#2}% - \edef\f@series{#3}% + \set@target@series{#3}% \edef\f@shape{#4}\selectfont \ignorespaces} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\usefont}{Drop m in usefont}% +% +%\DeclareRobustCommand\usefont[4]{\fontencoding{#1}% +% \edef\f@family{#2}% +% \edef\f@series{#3}% +% \edef\f@shape{#4}\selectfont +% \ignorespaces} +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/lthooks-code.pdf b/macros/latex/base/lthooks-code.pdf index e181e4bb27..5bb5d7899f 100644 Binary files a/macros/latex/base/lthooks-code.pdf and b/macros/latex/base/lthooks-code.pdf differ diff --git a/macros/latex/base/lthooks-doc.pdf b/macros/latex/base/lthooks-doc.pdf index 5949974141..1ca6ef3a6d 100644 Binary files a/macros/latex/base/lthooks-doc.pdf and b/macros/latex/base/lthooks-doc.pdf differ diff --git a/macros/latex/base/lthooks.dtx b/macros/latex/base/lthooks.dtx index e4ff7dd2ed..cc79892ca7 100644 --- a/macros/latex/base/lthooks.dtx +++ b/macros/latex/base/lthooks.dtx @@ -31,8 +31,8 @@ %%% From File: lthooks.dtx % % \begin{macrocode} -\def\lthooksversion{v1.0e} -\def\lthooksdate{2020/10/23} +\def\lthooksversion{v1.0g} +\def\lthooksdate{2020/12/18} % \end{macrocode} % %<*driver> @@ -222,11 +222,13 @@ % \begin{syntax} % \cs{AddToHook} \Arg{hook}\oarg{label}\Arg{code} % \end{syntax} -% Adds \meta{code} to the \meta{hook} labeled by \meta{label}. If -% the optional argument \meta{label} is not provided, if \cs{AddToHook} -% is used in a package/class, then the current -% package/class name is used, otherwise \hook{top-level} is -% used~(see section~\ref{sec:default-label}). +% Adds \meta{code} to the \meta{hook} labeled by \meta{label}. +% When the optional argument \meta{label} is not provided, the +% \meta{default label} is used (see section~\ref{sec:default-label}). +% If \cs{AddToHook} is used in a package/class, the +% \meta{default label} is the package/class name, otherwise it is +% \hook{top-level} (the \hook{top-level} label is treated +% differently: see section~\ref{sec:top-level}). % % If there already exists code under the \meta{label} then the new % \meta{code} is appended to the existing one (even if this is a reversed hook). @@ -234,10 +236,10 @@ % \meta{label}, first apply \cs{RemoveFromHook}. % % The hook doesn't have to exist for code to be added to -% it. However, if it is not declared later then obviously the +% it. However, if it is not declared, then obviously the % added \meta{code} will never be executed. This % allows for hooks to work regardless of package loading order and -% enables packages to add to hook of other packages without +% enables packages to add to hooks from other packages without % worrying whether they are actually used in the current document. % See section~\ref{sec:querying}. % @@ -251,10 +253,8 @@ % \cs{RemoveFromHook} \Arg{hook}\oarg{label} % \end{syntax} % Removes any code labeled by \meta{label} from the \meta{hook}. -% If the optional -% argument \meta{label} is not provided, if \cs{AddToHook} -% is used in a package/class, then the current -% package/class name is used, otherwise \hook{top-level} is used. +% When the optional argument \meta{label} is not provided, the +% \meta{default label} is used (see section~\ref{sec:default-label}). % % If the code for that \meta{label} wasn't yet added to the % \meta{hook}, an order is set so that when some code attempts to add @@ -273,7 +273,7 @@ % \medskip % % In contrast to the \texttt{voids} relationship between two labels -% in a \cs{DeclareHookrule} this is a destructive operation as the +% in a \cs{DeclareHookRule} this is a destructive operation as the % labeled code is removed from the hook data structure, whereas the % relationship setting can be undone by providing a different % relationship later. @@ -367,7 +367,8 @@ % token, a low-level \TeX{} error is raised (namely, the \meta{hook} is % expanded using \TeX's \cs{csname}\ldots\cs{endcsname}, as such, % Unicode characters are allowed in \meta{hook} and \meta{label} -% arguments). The arguments of \cs{UseHook} and \cs{UseOneTimeHook} are +% arguments). The arguments of \cs{UseHook}, \cs{UseOneTimeHook}, +% \cs{IfHookEmptyTF}, and \cs{IfHookExistsTF} are % processed much in the same way except that spaces are not trimmed % around the argument, for better performance. % @@ -377,10 +378,10 @@ % chunk and to prevent clashes. This should be the standard practice, % so this hook management code provides a shortcut to refer to the % current package in the name of a \meta{hook} and in a \meta{label}. -% If \meta{hook} name or \meta{label} consist just of a single dot +% If the \meta{hook} name or the \meta{label} consist just of a single dot % (|.|), or starts with a dot followed by a slash (|./|) then the dot % denotes the \meta{default label} (usually the current package or class -% name---see~\cs{DeclareDefaultHookLabel}). +% name---see~\cs{SetDefaultHookLabel}). % A \enquote{|.|} or \enquote{|./|} anywhere else in a \meta{hook} or in % \meta{label} is treated literally and is not replaced. % @@ -403,15 +404,15 @@ % \AddToHook {file/after/foo.tex}{code} % unchanged % \end{verbatim} % -% The \meta{default label} is automatically set to the name of the -% current package or class (using \cs{@currname}). If \cs{@currname} -% is not set (because the hook command is used outside of a package, or -% the current file wasn't loaded with \cs{usepackage} or -% \cs{documentclass}), then the \texttt{top-level} is used as the -% \meta{default label}. +% The \meta{default label} is automatically set equal to the name of the +% current package or class at the time the package is loaded. If the +% hook command is used outside of a package, or the current file wasn't +% loaded with \cs{usepackage} or \cs{documentclass}, then the +% \texttt{top-level} is used as the \meta{default label}. This may have +% exceptions---see \cs{PushDefaultHookLabel}. % % This syntax is available in all \meta{label} arguments and most -% \meta{hook}, both in the \LaTeXe{} interface, and the \LaTeX3 +% \meta{hook} arguments, both in the \LaTeXe{} interface, and the \LaTeX3 % interface described in section~\ref{sec:l3hook-interface}. % % Note, however, that the replacement of |.| by the \meta{default label} @@ -430,29 +431,104 @@ % In some cases, for example in large packages, one may want to separate % it in logical parts, but still use the main package name as % \meta{label}, then the \meta{default label} can be set using -% \cs{DeclareDefaultHookLabel}: +% \cs{SetDefaultHookLabel} or +% \cs{PushDefaultHookLabel}..\cs{PopDefaultHookLabel}. % -% \begin{function}{\DeclareDefaultHookLabel} +% \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel} % \begin{syntax} -% \cs{DeclareDefaultHookLabel} \Arg{default label} +% \cs{PushDefaultHookLabel} \Arg{default label} +% \quad \meta{code} +% \cs{PopDefaultHookLabel} % \end{syntax} -% Sets the \meta{default label} to be used in \meta{label} arguments. -% If \cs{DeclareDefaultHookLabel} is not used in the -% current package, \cs{@currname} is used instead. If \cs{@currname} -% is not set, the code is assumed to be in the main document, in which -% case \texttt{top-level} is used. -% -% The effect of \cs{DeclareDefaultHookLabel} holds for the current -% file, and is reset to the previous value when the file is closed. +% \cs{PushDefaultHookLabel} sets the current \meta{default label} to +% be used in \meta{label} arguments, or when replacing a leading +% ``|.|'' (see above). \cs{PopDefaultHookLabel} reverts the +% \meta{default label} to its previous value. +% +% Inside a package or class, the \meta{default label} is equal to the +% package or class name, unless explicitly changed. Everywhere else, +% the \meta{default label} is |top-level| (see +% section~\ref{sec:top-level}) unless explicitly changed. +% +% The effect of \cs{PushDefaultHookLabel} holds until the next +% \cs{PopDefaultHookLabel}. \cs{usepackage} (and \cs{RequirePackage} +% and \cs{documentclass}) internally use +% \begin{quote} +% \cs{PushDefaultHookLabel}\Arg{package name} \\ +% \null \quad \meta{package code} \\ +% \cs{PopDefaultHookLabel} +% \end{quote} +% to set the \meta{default label} for the package or class file. +% Inside the \meta{package code} the \meta{default label} can also be +% changed with \cs{SetDefaultHookLabel}. \cs{input} and other +% file input-related commands from the \LaTeX{} kernel do not use +% \cs{PushDefaultHookLabel}, so code within files loaded by these +% commands does \emph{not} get a dedicated \meta{label}! (that is, the +% \meta{default label} is the current active one when the file was +% loaded.) +% +% Packages that provide their own package-like interfaces +% (Ti\textit{k}Z's \cs{usetikzlibrary}, for example) can use +% \cs{PushDefaultHookLabel} and \cs{PopDefaultHookLabel} to set +% dedicated labels and emulate \cs{usepackage}-like hook behaviour +% within those contexts. +% +% The |top-level| label is treated differently, and is reserved to the +% user document, so it is not allowed to change the +% \meta{default label} to |top-level|. +% \end{function} +% +% \begin{function}{\SetDefaultHookLabel} +% \begin{syntax} +% \cs{SetDefaultHookLabel} \Arg{default label} +% \end{syntax} +% Similarly to \cs{PushDefaultHookLabel}, +% sets the current \meta{default label} to +% be used in \meta{label} arguments, or when replacing a leading +% ``|.|''. The effect holds until the label is changed again or until +% the next \cs{PopDefaultHookLabel}. The difference between +% \cs{PushDefaultHookLabel} and \cs{SetDefaultHookLabel} is that the +% latter does not save the current \meta{default label}. +% +% This command is useful when a large package is composed of several +% smaller packages, but all should have the same \meta{label}, so +% \cs{SetDefaultHookLabel} can be used at the beginning of each +% package file to set the correct label. +% +% \cs{SetDefaultHookLabel} is not allowed in the main document, where +% the \meta{default label} is |top-level| and there is no +% \cs{PopDefaultHookLabel} to end its effect. +% It is also not allowed to change the \meta{default label} to +% |top-level|. % \end{function} % +% \subsubsection{The \texttt{top-level} label} +% \label{sec:top-level} +% +% The |top-level| label, assigned to code added from the main document, +% is different from other labels. Code added to hooks (usually +% \cs{AtBeginDocument}) in the preamble is almost always to change +% something defined by a package, so it should go at the very end of the +% hook. +% +% Therefore, code added in the |top-level| is always executed at the end +% of the hook, regardless of where it was declared. If the hook is +% reversed (see \cs{NewReversedHook}), the |top-level| chunk is executed +% at the very beginning instead. +% +% Rules regarding |top-level| have no effect: if a user wants to have a +% specific set of rules for a code chunk, they should use a different +% label to said code chunk, and provide a rule for that label instead. +% +% The |top-level| label is exclusive for the user, so trying to add code +% with that label from a package results in an error. % % \subsubsection{Defining relations between hook code} % % The default assumption is that code added to hooks by different -% packages is independent and the order in which it is executed is -% irrelevant. While this is true in many case it is obviously false -% in many others. +% packages are independent and the order in which they are executed is +% irrelevant. While this is true in many cases it is obviously false +% in others. % % Before the hook management system was introduced % packages had to take elaborate precaution to determine of some other @@ -589,7 +665,8 @@ % its permanent code pool, or to its ``next'' token list. The hook % doesn't need to be declared to have code added to its code pool. % A hook is said to exist when it was declared with \cs{NewHook} or -% some variant thereof. +% some variant thereof. Generic \hook{file} and \hook{env} hooks are +% automatically declared when code is added to them. % % \begin{function}[EXP]{\IfHookEmptyTF} % \begin{syntax} @@ -650,6 +727,7 @@ % \item % any code executed on the next invocation only. % \end{itemize} +% \end{function} % % \cs{LogHook} prints the information to the |.log| file, and % \cs{ShowHook} prints them to the terminal/command window and starts @@ -660,6 +738,7 @@ % %^^A % Code for the listing below: %^^A \NewHook{example-hook} +%^^A \AddToHook{example-hook}{[code from 'top-level']} %^^A \AddToHook{example-hook}[foo]{[code from package 'foo']} %^^A \AddToHook{example-hook}[bar]{[from package 'bar']} %^^A \AddToHook{example-hook}[baz]{[package 'baz' is here]} @@ -680,13 +759,15 @@ % > foo -> [code from package 'foo'] % > bar -> [from package 'bar'] % > baz -> [package 'baz' is here] +% > Document-level (top-level) code (executed last): +% > -> [code from 'top-level'] % > Extra code for next invocation: % > -> [one-time code] % > Rules: % > foo|baz with relation > % > baz|bar with default relation < % > Execution order (after applying rules): -% > bar, baz, foo. +% > baz, foo, bar. % \end{verbatim} % % In the listing above, lines~3 to~5 show the three code chunks added @@ -695,7 +776,18 @@ % \quad \meta{label}\verb| -> |\meta{code} % \end{quote} % -% Line~7 shows the code chunk for the next execution of the hook in +% Line~7 shows the code chunk added by the user in the main document +% (labeled |top-level|) in the format +% \begin{quote} +% \quad\verb|Document-level (top-level) code (executed |%^^A +% \meta{first\texttt{\string|}last}\verb|):|\\ +% \quad\verb| -> |\meta{\texttt{top-level} code} +% \end{quote} +% This code will be either the first or last code executed by the hook +% (|last| if the hook is normal, |first| if it is reversed). This +% chunk is not affected by rules and does not take part in sorting. +% +% Line~9 shows the code chunk for the next execution of the hook in % the format % \begin{quote} % \quad \verb|-> |\meta{next-code} @@ -705,7 +797,7 @@ % earlier, which can only be removed from that hook by doing % \verb|\RemoveFromHook{|\meta{label}|}[example-hook]|. % -% Lines~9 and~10 show the rules declared that affect this hook in the +% Lines~11 and~12 show the rules declared that affect this hook in the % format % \begin{quote} % \quad \meta{label-1}\verb+|+\meta{label-2}| with |%^^A @@ -717,9 +809,8 @@ % to \meta{label-1} and \meta{label-2} in \emph{all} hooks, (unless % overrided by a non-default relation). % -% Finally, line~12 lists the labels in the hook after sorting; +% Finally, line~14 lists the labels in the hook after sorting; % that is, in the order they will be executed when the hook is used. -% \end{function} % % % \subsubsection{Debugging hook code} @@ -749,8 +840,9 @@ % \begin{function} % {\hook_new:n,\hook_new_reversed:n,\hook_new_pair:nn} % \begin{syntax} -% \cs{hook_new:n}\Arg{hook} -% \cs{hook_new_pair:nn}\Arg{hook-1}\Arg{hook-2} +% \cs{hook_new:n} \Arg{hook} +% \cs{hook_new_reversed:n} \Arg{hook} +% \cs{hook_new_pair:nn} \Arg{hook-1} \Arg{hook-2} % \end{syntax} % Creates a new \meta{hook} with normal or reverse ordering of code % chunks. \cs{hook_new_pair:nn} creates a pair of such hooks with @@ -782,7 +874,6 @@ % Changes the \Arg{hook} status so that from now on any addition to % the hook code is executed immediately. Then execute any % \Arg{hook} code already set up. -% \fmi{better L3 name?} % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. @@ -954,17 +1045,19 @@ % \texttt{packageB}, \texttt{packageC} which you can verify with % \cs{ShowHook}\texttt{\{myhook\}}: %\begin{verbatim} -% The hook 'myhook': -% Code chunks: -% packageA -> \typeout {A} -% packageB -> \typeout {B} -% packageC -> \typeout {C} -% Extra code next invocation: -% --- -% Rules: -% --- -% Execution order: -% packageA, packageB, packageC +% -> The hook 'myhook': +% > Code chunks: +% > packageA -> \typeout {A} +% > packageB -> \typeout {B} +% > packageC -> \typeout {C} +% > Document-level (top-level) code (executed last): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > --- +% > Execution order: +% > packageA, packageB, packageC. %\end{verbatim} % The reason is that the code chunks are internally saved in a property list % and the initial order of such a property list is the order in @@ -988,17 +1081,19 @@ %\end{verbatim} % instead of the previous lines we get %\begin{verbatim} -% The hook 'myhook': -% Code chunks: -% packageA -> \typeout {A} -% packageB -> \typeout {B} -% packageC -> \typeout {C} -% Extra code next invocation: -% --- -% Rules: -% packageA|packageB with relation before -% Execution order (after applying rules): -% packageA, packageC, packageB +% -> The hook 'myhook': +% > Code chunks: +% > packageA -> \typeout {A} +% > packageB -> \typeout {B} +% > packageC -> \typeout {C} +% > Document-level (top-level) code (executed last): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > packageB|packageA with relation > +% > Execution order (after applying rules): +% > packageA, packageC, packageB. %\end{verbatim} % As you can see the code chunks are still in the same order, but % in the execution order for the labels \texttt{packageB} and @@ -1010,7 +1105,7 @@ % doesn't run at all as there is nothing to resolve). % Incidentally, if we had instead specified the redundant rule %\begin{verbatim} -% \DeclareHookRule{myhook}{packageB}{before}{label-3} +% \DeclareHookRule{myhook}{packageB}{before}{packageC} %\end{verbatim} % the execution order would not have changed. % @@ -1039,17 +1134,17 @@ % \AddToHook{env/quote/after} [package-1]{\end{itshape}} %\end{verbatim} % As a result, all quotes will be in italics. -% Now suppose further that the user wants the quotes also in blue -% and therefore adds: +% Now suppose further that another |package-too| makes the quotes +% also in blue and therefore adds: %\begin{verbatim} % \usepackage{color} -% \AddToHook{env/quote/before}{\begin{color}{blue}} -% \AddToHook{env/quote/after} {\end{color}} +% \AddToHook{env/quote/before}[package-too]{\begin{color}{blue}} +% \AddToHook{env/quote/after} [package-too]{\end{color}} %\end{verbatim} % Now if the \hook{env/quote/after} hook would be a normal hook we % would get the same execution order in both hooks, namely: %\begin{verbatim} -% package-1, top-level +% package-1, package-too %\end{verbatim} % (or vice versa) and as a result, would get: %\begin{verbatim} @@ -1063,16 +1158,18 @@ % the correct sequence and \cs{ShowHook} would give us the % following output: %\begin{verbatim} -% The hook 'env/quote/after': -% Code chunks: -% package-1 -> \end {itshape} -% top-level -> \end {color} -% Extra code next invocation: -% --- -% Rules: -% --- -% Execution order (after reversal): -% top-level, package-1 +% -> The hook 'env/quote/after': +% > Code chunks: +% > package-1 -> \end {itshape} +% > package-too -> \end {color} +% > Document-level (top-level) code (executed first): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > --- +% > Execution order (after reversal): +% > package-too, package-1. %\end{verbatim} % % The reversal of the execution order happens before applying any @@ -1206,13 +1303,15 @@ % \hook{begindocument} % (which is executed inside \verb=\begin{document}=). % However, all code added this way is labeled with the label -% \hook{top-level} if done outside of a package or class or with the -% package/class name if called inside such a file. +% \hook{top-level} (see section~\ref{sec:top-level}) +% if done outside of a package or class or with the +% package/class name if called inside such a file +% (see section~\ref{sec:default-label}). % % This way one can add further code to the hook using % \cs{AddToHook} or \cs{AtBeginDocument} using a different label % and explicitly order the code chunks as necessary, e.g., run some -% code before or after the \hook{top-level} code. When using the +% code before or after another package's code. When using the % optional argument the call is equivalent to running % \cs{AddToHook} \texttt{\{begindocument\}} \oarg{label} % \Arg{code}. @@ -1251,7 +1350,7 @@ % The few hooks that existed previously in \LaTeXe{} used internally % commands such as \cs{@begindocumenthook} and packages sometimes % augemented them directly rather than working through -% \cs{AtBeginDocumement}. For that reason there is currently support +% \cs{AtBeginDocument}. For that reason there is currently support % for this, that is, if the system detects that such an internal % legacy hook command contains code it adds it to the new hook % system under the label \texttt{legacy} so that it doesn't get @@ -1333,8 +1432,8 @@ % \cs{BeforeBeginEnvironment} \oarg{label} \Arg{code} % \end{syntax} % This declaration adds to the \hook{env/\meta{env}/before} hook -% using by default the current package or class name as a label or -% \texttt{top-level} if used in the document directly. +% using the \meta{label}. If \meta{label} is not given, the +% \meta{default label} is used (see section~\ref{sec:default-label}). % \end{function} % % \begin{function}{\AtBeginEnvironment} @@ -1774,6 +1873,37 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_tl_set:Nn,\@@_tl_set:cn,\@@_tl_set:cx} +% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:cn,\@@_tl_gset:co,\@@_tl_gset:cx} +% \begin{macro}{\@@_tl_gput_right:Nn,\@@_tl_gput_right:No,\@@_tl_gput_right:cn} +% \begin{macro}{\@@_tl_gput_left:Nn,\@@_tl_gput_left:No} +% \begin{macro}{\@@_tl_gclear:N,\@@_tl_gclear:c} +% \begin{macro}{\@@_tl_gset_eq:NN} +% Private copies of a few \pkg{expl3} functions. \pkg{l3debug} will +% only add debugging to the public names, not to these copies, so we +% don't have to use \cs{debug_suspend:} and \cs{debug_resume:} +% everywhere. +% \begin{macrocode} +\cs_new_eq:NN \@@_tl_set:Nn \tl_set:Nn +\cs_generate_variant:Nn \@@_tl_set:Nn { cn, cx } +\cs_new_eq:NN \@@_tl_gset:Nn \tl_gset:Nn +\cs_generate_variant:Nn \@@_tl_gset:Nn { cn, co, cx } +\cs_new_eq:NN \@@_tl_gput_right:Nn \tl_gput_right:Nn +\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No, cn } +\cs_new_eq:NN \@@_tl_gput_left:Nn \tl_gput_left:Nn +\cs_generate_variant:Nn \@@_tl_gput_left:Nn { No } +\cs_new_protected:Npn \@@_tl_gclear:N #1 + { \@@_tl_gset_eq:NN #1 \c_empty_tl } +\cs_generate_variant:Nn \@@_tl_gclear:N { c } +\cs_new_eq:NN \@@_tl_gset_eq:NN \tl_gset_eq:NN +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % % \subsection{Providing new hooks} % @@ -1808,6 +1938,13 @@ % $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed % ones. % +% \item[\cs{@@_toplevel~\meta{name}}] This token list stores the code +% inserted in the hook from the user's document, in the |top-level| +% label. This label is special, and doesn't participate in sorting. +% Instead, all code is appended to it and executed after (or before, +% if the hook is reversed) the normal +% hook code, but before the |next| code chunk. +% % \item[\cs{@@_next~\meta{name}}] Finally there is extra code % (normally empty) that is used on the next invocation of the hook % (and then deleted). This can be used to define some special @@ -1890,15 +2027,16 @@ % \begin{macro}{\@@_declare:n} % This function declares the basic data structures for a hook without % actually declaring the hook itself. This is needed to allow adding -% to undeclared hooks. Here it is unnecessary to check whether both -% variables exist, since both are declared at the same time (either -% both exist, or neither). +% to undeclared hooks. Here it is unnecessary to check whether all +% variables exist, since all three are declared at the same time +% (either all of them exist, or none). % \begin{macrocode} \cs_new_protected:Npn \@@_declare:n #1 { \@@_if_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } + \tl_new:c { @@_toplevel~#1 } \tl_new:c { @@_next~#1 } } } @@ -1951,13 +2089,6 @@ \cs_new_protected:Npn \@@_include_legacy_code_chunk:n #1 { % \end{macrocode} -% If the \pkg{expl3} code is run with checking on then assigning or -% using non L3 names such as \cs{@enddocumenthook} with \pkg{expl3} -% functions will trigger warnings so we run this code with -% debugging explicitly suspended. -% \begin{macrocode} - \debug_suspend: -% \end{macrocode} % If the macro doesn't exist (which is the usual case) then nothing % needs to be done. % \begin{macrocode} @@ -1975,10 +2106,9 @@ % Once added to the hook, we need to clear it otherwise it might % get added again later if the hook data gets updated. % \begin{macrocode} - \tl_gclear:c { @#1hook } + \@@_tl_gclear:c { @#1hook } } } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -1990,79 +2120,76 @@ % \begin{macro}[EXP]{\@@_parse_label_default:n} % This macro checks if a label was given (not \cs{c_novalue_tl}), and % if so, tries to parse the label looking for a leading \verb|.| to -% replace for \cs{@currname}. Otherwise \cs{@@_currname_or_default:n} -% is used to pick \cs{@currname} or the fallback value. -% -% The default |top-level| is hard-coded here. It once was an -% argument, but it's no longer needed. \pho{can't remember why} +% replace by \cs{@@_currname_or_default:}. % \begin{macrocode} \cs_new:Npn \@@_parse_label_default:n #1 { \tl_if_novalue:nTF {#1} - { \@@_currname_or_default:n { top-level } } - { - \tl_trim_spaces_apply:nN {#1} - \@@_parse_dot_label:nn { top-level } - } + { \@@_currname_or_default: } + { \tl_trim_spaces_apply:nN {#1} \@@_parse_dot_label:n } } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_parse_dot_label:nn} +% \begin{macro}[EXP]{\@@_parse_dot_label:n} % \begin{macro}[EXP]{ -% \@@_parse_dot_label:nw, +% \@@_parse_dot_label:w, % \@@_parse_dot_label_cleanup:w, -% \@@_parse_dot_label_aux:nw +% \@@_parse_dot_label_aux:w % } % Start by checking if the label is empty, which raises an error, and % uses the fallback value. If not, % split the label at a \verb|./|, if any, and check if no tokens are % before the \verb|./|, or if the only character is a \verb|.|. % If these requirements are fulfilled, the leading -% \verb|.| is replaced with \cs{@@_currname_or_default:n}. Otherwise +% \verb|.| is replaced with \cs{@@_currname_or_default:}. Otherwise % the label is returned unchanged. % \begin{macrocode} -\cs_new:Npn \@@_parse_dot_label:nn #1 #2 +\cs_new:Npn \@@_parse_dot_label:n #1 { \tl_if_empty:nTF {#1} { - \msg_expandable_error:nnn { hooks } { empty-label } {#2} - #2 + \msg_expandable_error:nn { hooks } { empty-label } + \@@_currname_or_default: } { \str_if_eq:nnTF {#1} { . } - { \@@_currname_or_default:n {#2} } - { \@@_parse_dot_label:nw {#2} #1 ./ \s_@@_mark } + { \@@_currname_or_default: } + { \@@_parse_dot_label:w #1 ./ \s_@@_mark } } } -\cs_new:Npn \@@_parse_dot_label:nw #1 #2 ./ #3 \s_@@_mark +\cs_new:Npn \@@_parse_dot_label:w #1 ./ #2 \s_@@_mark { - \tl_if_empty:nTF {#2} - { \@@_parse_dot_label_aux:nw {#1} #3 \s_@@_mark } + \tl_if_empty:nTF {#1} + { \@@_parse_dot_label_aux:w #2 \s_@@_mark } { - \tl_if_empty:nTF {#3} - { \@@_make_name:n {#2} } - { \@@_parse_dot_label_cleanup:w #2 ./ #3 \s_@@_mark } + \tl_if_empty:nTF {#2} + { \@@_make_name:n {#1} } + { \@@_parse_dot_label_cleanup:w #1 ./ #2 \s_@@_mark } } } \cs_new:Npn \@@_parse_dot_label_cleanup:w #1 ./ \s_@@_mark {#1} -\cs_new:Npn \@@_parse_dot_label_aux:nw #1 #2 ./ \s_@@_mark - { \@@_currname_or_default:n {#1} / \@@_make_name:n {#2} } +\cs_new:Npn \@@_parse_dot_label_aux:w #1 ./ \s_@@_mark + { \@@_currname_or_default: / \@@_make_name:n {#1} } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_currname_or_default:n} +% \begin{macro}[EXP]{\@@_currname_or_default:} % Uses \cs{g_@@_hook_curr_name_tl} if it is set, otherwise tries -% \cs{@currname}. If neither is set, uses the fallback value -% \verb|#1| (usually \texttt{top-level}). +% \cs{@currname}. If neither is set, raises an error and uses the +% fallback value \verb|label-missing|. % \begin{macrocode} -\cs_new:Npn \@@_currname_or_default:n #1 +\cs_new:Npn \@@_currname_or_default: { \tl_if_empty:NTF \g_@@_hook_curr_name_tl { \tl_if_empty:NTF \@currname - { \@@_make_name:n {#1} } + { + \msg_expandable_error:nnn { hooks } { should-not-happen } + { Empty~default~label. } + \@@_make_name:n { label-missing } + } { \@currname } } { \g_@@_hook_curr_name_tl } @@ -2213,14 +2340,33 @@ % \end{macrocode} % Then try to get the code chunk labeled \verb=#2= from the hook. % If there's code already there, then append \verb=#3= to that, -% otherwise just put \verb=#3=. +% otherwise just put \verb=#3=. If the current label is |top-level|, +% the code is added to a dedicated token list +% \cs[no-index]{@@_toplevel~\meta{hook}} that goes at the end of the +% hook (or at the beginning, for a reversed hook), just before +% \cs[no-index]{@@_next~\meta{hook}}. +% \begin{macrocode} + \str_if_eq:nnTF {#2} { top-level } + { + \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } + { +% \end{macrocode} +% If the hook's basic structure does not exist, we need to declare it +% with \cs{@@_declare:n}. % \begin{macrocode} - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + \@@_declare:n {#1} + \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} + } + { \msg_error:nnn { hooks } { misused-top-level } {#1} } + } { - \prop_gput:cno { g_@@_#1_code_prop } {#2} - { \l_@@_return_tl #3 } + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { + \prop_gput:cno { g_@@_#1_code_prop } {#2} + { \l_@@_return_tl #3 } + } + { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } } - { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } } % \end{macrocode} % \end{macro} @@ -2434,24 +2580,48 @@ % hook before its defined (see section~\ref{sec:querying}). % \begin{macrocode} \@@_if_exist:nTF {#1} + { % \end{macrocode} % Then remove the chunk and run \cs{@@_update_hook_code:n} so % that the execution token list reflects the change if we are after % \verb=\begin{document}=. +% +% If all code is to be removed, clear the code pool +% \cs[no-index]{g_@@_\meta{hook}_code_prop}, the top-level code +% \cs[no-index]{@@_toplevel~\meta{hook}}, and the next-execution code +% \cs[no-index]{@@_next~\meta{hook}}. % \begin{macrocode} - { \str_if_eq:nnTF {#2} {*} - { \prop_gclear:c { g_@@_#1_code_prop } } { + \prop_gclear:c { g_@@_#1_code_prop } + \@@_tl_gclear:c { @@_toplevel~#1 } + \@@_tl_gclear:c { @@_next~#1 } + } + { +% \end{macrocode} +% If the label is |top-level| then clear the token list, as all code +% there is under the same label. Marked removal is not implemented +% for |top-level| because it is hard to reliably know that no code +% was added to \cs[no-index]{@@_toplevel~\meta{hook}} (granted that +% an empty code could be interpreted as that, but then it differs in +% behaviour from other labels, in which an empty chunk is still valid +% for removal). Besides, it doesn't make much (if any) sense for +% packages to remove |top-level| code. So here the chunk is just +% cleared unconditionally. +% \begin{macrocode} + \str_if_eq:nnTF {#2} { top-level } + { \@@_tl_gclear:c { @@_toplevel~#1 } } + { % \end{macrocode} -% Check if the label being removed exists in the code pool. If it does, -% just call \cs{@@_gremove_code_do:nn} to do the removal, otherwise mark it -% to be removed. +% Otherwise check if the label being removed exists in the code pool. +% If it does, just call \cs{@@_gremove_code_do:nn} to do the removal, +% otherwise mark it to be removed. % \begin{macrocode} - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl - { \@@_gremove_code_do:nn } - { \@@_mark_removal:nn } - {#1} {#2} + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { \@@_gremove_code_do:nn } + { \@@_mark_removal:nn } + {#1} {#2} + } } % \end{macrocode} % Finally update the code, if the hook exists. @@ -2470,6 +2640,7 @@ % \end{macrocode} % % \begin{macro}{\@@_gremove_code_do:nn} +% Remove code for a given label. % \begin{macrocode} \cs_new_protected:Npn \@@_gremove_code_do:nn #1 #2 { \prop_gremove:cn { g_@@_#1_code_prop } {#2} } @@ -2605,7 +2776,6 @@ % Then we call the function to handle the given rule. Throw an error if the % rule is invalid. % \begin{macrocode} - \debug_suspend: \cs_if_exist_use:cTF { @@_rule_#3_gset:nnn } { {#1} {#2} {#4} @@ -2613,7 +2783,6 @@ } { \msg_error:nnnnnn { hooks } { unknown-rule } {#1} {#2} {#3} {#4} } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -2639,7 +2808,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_before_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { < } { > } } } \cs_new_eq:cN { @@_rule_<_gset:nnn } \@@_rule_before_gset:nnn @@ -2648,7 +2817,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_after_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } { \@@_label_ordered:nnTF {#3} {#2} { < } { > } } } \cs_new_eq:cN { @@_rule_>_gset:nnn } \@@_rule_after_gset:nnn @@ -2661,7 +2830,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_voids_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { -> } { <- } } } % \end{macrocode} @@ -2675,9 +2844,9 @@ % together in hook |#1|. % \begin{macrocode} \cs_new_protected:cpn { @@_rule_incompatible-error_gset:nnn } #1#2#3 - { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } \cs_new_protected:cpn { @@_rule_incompatible-warning_gset:nnn } #1#2#3 - { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } % \end{macrocode} % \end{macro} % @@ -2722,7 +2891,7 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_if_label_case:nnnnn} -% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNn} +% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNn} % (once with \cs{str_if_eq:nn} and again with \cs{@@_label_ordered:nn}), % we use a three-way branching macro that will compare |#1| and |#2| % and expand to \cs{use_i:nnn} if they are equal, \cs{use_ii:nn} if @@ -2800,7 +2969,6 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_initialize_hook_code:n #1 { - \debug_suspend: \@@_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~ '#1' \on@line :^^J} } % \end{macrocode} @@ -2815,17 +2983,22 @@ % If there aren't any code % chunks for the current hook, there is no point in even starting % the sorting routine so we make a quick test for that and in that -% case just update \cs{@@~\meta{hook}} to hold the next -% code. If there are code chunks we call -% \cs{@@_initialize_single:NNNn} and pass to it ready made csnames +% case just update \cs{@@~\meta{hook}} to hold the |top-level| and +% |next| code chunks. If there are code chunks we call +% \cs{@@_initialize_single:NNn} and pass to it ready made csnames % as they are needed several times inside. This way we save a bit % on processing time if we do that up front. % \begin{macrocode} \hook_if_exist:nT {#1} { \prop_if_empty:cTF {g_@@_#1_code_prop} - { \tl_gset:co { @@~#1 } - { \cs:w @@_next~#1 \cs_end: } } + { + \@@_tl_gset:co { @@~#1 } + { + \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: + \cs:w @@_next~#1 \cs_end: + } + } { % \end{macrocode} % By default the algorithm sorts the code chunks and then saves the @@ -2836,9 +3009,9 @@ % in preparation is to change two definitions used later on. % \begin{macrocode} \@@_if_reversed:nTF {#1} - { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_left:NV + { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_left:Nn \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV } - { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_right:NV + { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_right:Nn \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } % \end{macrocode} % @@ -2848,9 +3021,8 @@ % save the old code property list so that it can be restored later. % \begin{macrocode} \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } - \@@_initialize_single:cccn - { @@~#1 } { @@_next~#1 } - { g_@@_#1_labels_clist } {#1} + \@@_initialize_single:ccn + { @@~#1 } { g_@@_#1_labels_clist } {#1} % \end{macrocode} % For debug display we want to keep track of those hooks that % actually got code added to them, so we record that in plist. We @@ -2862,7 +3034,6 @@ \g_@@_used_prop {#1}{} } } } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -2918,12 +3089,13 @@ % \end{macro} % % -% \begin{macro}{\@@_initialize_single:NNNn,\@@_initialize_single:cccn} +% \begin{macro}{\@@_initialize_single:NNn,\@@_initialize_single:ccn} % -% \cs{@@_initialize_single:NNNn} implements the sorting of the code +% \cs{@@_initialize_single:NNn} implements the sorting of the code % chunks for a hook and saves the result in the token list for fast -% execution (\verb=#3=). The arguments are \meta{hook-code-plist}, -% \meta{hook-code-tl}, \meta{hook-next-code-tl}, +% execution (\verb=#4=). The arguments are \meta{hook-code-plist}, +% \meta{hook-code-tl}, \meta{hook-top-level-code-tl}, +% \meta{hook-next-code-tl}, % \meta{hook-ordered-labels-clist} and \meta{hook-name} (the latter % is only used for debugging---the \meta{hook-rule-plist} is accessed % using the \meta{hook-name}). @@ -2935,8 +3107,12 @@ % far as possible. The result is a restriction I do not test for at % the moment: a label can't be equal to the number 0! \fmi{Needs % checking for, just in case} +% +% ^^A #1 <- \@@~#1 +% ^^A #2 <- \g_@@_#1_labels_clist +% ^^A #3 <- #1 % \begin{macrocode} -\cs_new_protected:Npn \@@_initialize_single:NNNn #1#2#3#4 +\cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 { % \end{macrocode} % Step T1: Initialize the data structure \ldots @@ -2947,7 +3123,7 @@ % % Store the name of the hook: % \begin{macrocode} - \tl_set:Nn \l_@@_cur_hook_tl {#4} + \tl_set:Nn \l_@@_cur_hook_tl {#3} % \end{macrocode} % % We loop over the property list holding the code and record all @@ -2961,7 +3137,7 @@ { \int_incr:N \l_@@_labels_int \seq_put_right:Nn \l_@@_labels_seq {##1} - \tl_set:cn { \@@_tl_csname:n {##1} }{0} + \@@_tl_set:cn { \@@_tl_csname:n {##1} } { 0 } \seq_clear_new:c { \@@_seq_csname:n {##1} } } % \end{macrocode} @@ -2987,7 +3163,7 @@ { \prop_map_break: } { \@@_apply_label_pair:nnn {##1} {####1} } { \@@_apply_label_pair:nnn {####1} {##1} } - {#4} + {#3} } } % \end{macrocode} @@ -3014,8 +3190,8 @@ % \end{macrocode} % % \begin{macrocode} - \tl_gclear:N #1 - \clist_gclear:N #3 + \@@_tl_gclear:N #1 + \clist_gclear:N #2 % \end{macrocode} % % The whole loop combines steps T5--T7: @@ -3027,11 +3203,11 @@ % \begin{macrocode} \int_decr:N \l_@@_labels_int \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl - \@@_tl_gput:NV #1 \l_@@_return_tl + \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl % \end{macrocode} % % \begin{macrocode} - \@@_clist_gput:NV #3 \l_@@_front_tl + \@@_clist_gput:NV #2 \l_@@_front_tl \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } % \end{macrocode} % @@ -3078,27 +3254,31 @@ } % \end{macrocode} % After we have added all hook code to \verb=#1= we finish it off -% with adding extra code for a one time execution. That is stored -% in \verb=#2= but is normally empty. -% \begin{macrocode} - \tl_gput_right:Nn #1 {#2} +% with adding extra code for the |top-level| (\verb=#2=) and for one +% time execution (\verb=#3=). These should normally be empty. The +% |top-level| code is added with \cs{@@_tl_gput:Nn} as that might +% change for a reversed hook (then |top-level| is the very first code +% chunk added). The |next| code is always added last. +% \begin{macrocode} + \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } + \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } } % \end{macrocode} -% +% % \begin{macrocode} -\cs_generate_variant:Nn \@@_initialize_single:NNNn {ccc} +\cs_generate_variant:Nn \@@_initialize_single:NNn { cc } % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_tl_gput:NV,\@@_clist_gput:NV} +% \begin{macro}{\@@_tl_gput:Nn,\@@_clist_gput:NV} % These append either on the right (normal hook) or on the left % (reversed hook). This is setup up in % \cs{@@_initialize_hook_code:n}, elsewhere their behavior is undefined. % \begin{macrocode} -\cs_new:Npn \@@_tl_gput:NV {\ERROR} -\cs_new:Npn \@@_clist_gput:NV {\ERROR} +\cs_new:Npn \@@_tl_gput:Nn { \ERROR } +\cs_new:Npn \@@_clist_gput:NV { \ERROR } % \end{macrocode} % \end{macro} % @@ -3347,7 +3527,8 @@ % \begin{macrocode} \hook_if_exist:nF {#1} { \@@_log_line:x { is~not~declared! } } - \@@_if_exist:nTF {#1} + \hook_if_empty:nTF {#1} + { #2 { The~hook~is~empty } } { \@@_log_line:x { Code~chunks: } \prop_if_empty:cTF { g_@@_#1_code_prop } @@ -3357,9 +3538,25 @@ { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } } % \end{macrocode} -% +% +% If there is code in the |top-level| token list, print it: % \begin{macrocode} - \@@_log_line:x { Extra~code~for~next~invocation:} + \@@_log_line:x + { + Document-level~(top-level)~code + \hook_if_exist:nT {#1} + { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } : + } + \@@_log_line_indent:x + { + \tl_if_empty:cTF { @@_toplevel~#1 } + { --- } + { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } + } +% \end{macrocode} +% +% \begin{macrocode} + \@@_log_line:x { Extra~code~for~next~invocation: } \@@_log_line_indent:x { \tl_if_empty:cTF { @@_next~#1 } @@ -3427,7 +3624,6 @@ } } } - { #2 { The~hook~is~empty. } } } % \end{macrocode} % @@ -3478,7 +3674,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_list_one_rule:nnn #1#2#3 { - \@@_list_if_rule_exists:nnnF {#1} {#2} {#3} { } + \@@_list_if_rule_exists:nnnF {#1} {#2} {#3} { \@@_list_if_rule_exists:nnnF {#1} {#2} { ?? } { } } } \cs_new_protected:Npn \@@_list_if_rule_exists:nnnF #1#2#3 @@ -3486,7 +3682,9 @@ \if_cs_exist:w g_@@_ #3 _rule_ #1 | #2 _tl \cs_end: \exp_args:Nv \@@_tmp:w { g_@@_ #3 _rule_ #1 | #2 _tl } { #1 | #2 } {#3} + \exp_after:wN \use_none:nn \fi: + \use:n } % \end{macrocode} % \end{macro} @@ -3528,12 +3726,10 @@ { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 { - \debug_suspend: \@@_declare:n {#1} \hook_if_exist:nTF {#1} { \@@_gput_next_do:nn {#1} {#2} } { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } - \debug_resume: } \cs_new_protected:Npn \@@_gput_next_do:nn #1 { @@ -3556,8 +3752,8 @@ \tl_if_empty:cT { @@~#2 } { \@@_update_hook_code:n {#2} } \tl_if_empty:NT #1 - { \tl_gset:Nn #1 { \@@_clear_next:n {#2} } } - \tl_gput_right:Nn #1 + { \@@_tl_gset:Nn #1 { \@@_clear_next:n {#2} } } + \@@_tl_gput_right:Nn #1 } \cs_new_protected:Npn \@@_clear_next:n #1 { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } @@ -3565,7 +3761,6 @@ % \end{macro} % \end{macro} % -% % \subsection{Using the hook} % % \begin{macro}{\hook_use:n} @@ -3720,8 +3915,9 @@ % % \begin{macro}[pTF]{\hook_if_empty:n} % Test if a hook is empty (that is, no code was added to that hook). -% A hook being empty means that \emph{both} its -% \cs[no-index]{g_@@_\meta{hook}_code_prop} and its +% A \meta{hook} being empty means that all three of its +% \cs[no-index]{g_@@_\meta{hook}_code_prop}, its +% \cs[no-index]{@@_toplevel~\meta{hook}} and its % \cs[no-index]{@@_next~\meta{hook}} are empty. % \begin{macrocode} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } @@ -3730,7 +3926,11 @@ { \bool_lazy_and:nnTF { \prop_if_empty_p:c { g_@@_#1_code_prop } } - { \tl_if_empty_p:c { @@_next~#1 } } + { + \bool_lazy_and_p:nn + { \tl_if_empty_p:c { @@_toplevel~#1 } } + { \tl_if_empty_p:c { @@_next~#1 } } + } { \prg_return_true: } { \prg_return_false: } } @@ -3812,9 +4012,20 @@ % % \begin{macrocode} \msg_new:nnn { hooks } { empty-label } - { Empty~code~label~\msg_line_context:.~Using~`#1'~instead. } + { + Empty~code~label~\msg_line_context:.~ + Using~`\@@_currname_or_default:'~instead. + } % \end{macrocode} -% +% +% \begin{macrocode} +\msg_new:nnn { hooks } { no-default-label } + { + Missing~(empty)~default~label~\msg_line_context:. \\ + This~command~was~ignored. + } +% \end{macrocode} +% % \begin{macrocode} \msg_new:nnnn { hooks } { unknown-rule } { Unknown~ relationship~ `#3'~ @@ -3834,6 +4045,51 @@ % \end{macrocode} % % \begin{macrocode} +\msg_new:nnnn { hooks } { misused-top-level } + { + Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\ + 'top-level'~is~reserved~for~the~user's~document. + } + { + The~'top-level'~label~is~meant~for~user~code~only,~and~should~only~ + be~used~(sparingly)~in~the~main~document.~Use~the~default~label~ + '\@@_currname_or_default:'~for~this~\@cls@pkg,~or~another~ + suitable~label. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { set-top-level } + { + You~cannot~change~the~default~label~#1~`top-level'.~Illegal \\ + \use:nn { ~ } { ~ } \iow_char:N \\#2{#3} \\ + \msg_line_context:. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { ddhl-deprecated } + { + \iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\ + Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\ + The~deprecated~name~will~be~removed~in~the~next~release. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { extra-pop-label } + { + Extra~\iow_char:N \\PopDefaultHookLabel. \\ + This~command~will~be~ignored. + } +\msg_new:nnn { hooks } { missing-pop-label } + { + Missing~\iow_char:N \\PopDefaultHookLabel. \\ + The~label~`#1'~was~pushed~but~never~popped.~Something~is~wrong. + } +% \end{macrocode} +% +% \begin{macrocode} \msg_new:nnn { hooks } { should-not-happen } { ERROR!~This~should~not~happen.~#1 \\ @@ -3879,39 +4135,77 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\SetDefaultHookLabel} +% \begin{macro}{\PushDefaultHookLabel} +% \begin{macro}{\PopDefaultHookLabel} % \begin{macro}{\DeclareDefaultHookLabel} -% \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_pop:} +% \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_push_aux:n} +% \begin{macro}{\@@_curr_name_pop:} +% \begin{macro}{\@@_end_document_label_check:} % The token list \cs{g_@@_hook_curr_name_tl} stores the name of the % current package/file to be used as label for hooks. % Providing a consistent interface is tricky, because packages can % be loaded within packages, and some packages may not use -% \cs{DeclareDefaultHookLabel} to change the default label (in which case -% \cs{@currname} is used, if set). +% \cs{SetDefaultHookLabel} to change the default label (in which +% case \cs{@currname} is used). % -% To pull that off, we keep a stack that contains the default label -% for each level of input. The bottom of the stack contains the -% default label for the top-level. Since the string \verb|top-level| -% is hardcoded, here this item of the stack is empty. Also, since -% we're in an input level, add \verb|lthooks| to the stack as well. -% This stack should never go empty. An empty entry is added to the -% stack to account for the \verb|top-level|. The item is empty so -% that the hard-coded default is used, but a call to -% \cs{DeclareDefaultHookLabel} will change it if needed. +% To pull that one off, we keep a stack that contains the default +% label for each level of input. The bottom of the stack contains the +% default label for the |top-level| (this stack should never go +% empty). If we're building the format, set the default label to be +% |top-level|: % \begin{macrocode} -\seq_gpush:Nn \g_@@_name_stack_seq { } +\tl_gset:Nn \g_@@_hook_curr_name_tl { top-level } % \end{macrocode} % +% Then, in case we're in \pkg{latexrelease} we push something on +% the stack to support roll forward. But in some rare cases, +% \pkg{latexrelease} may be loaded inside another package (notably +% \pkg{platexrelease}), so we'll first push the |top-level| entry: +% \begin{macrocode} +%\seq_gput_right:Nn \g_@@_name_stack_seq { top-level } +% \end{macrocode} +% then we dissect the \cs{@currnamestack}, adding \cs{@currname} to +% the stack: +% \changes{v1.0f}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\cs_set_protected:Npn \@@_tmp:w #1 #2 #3 +% { +% \quark_if_recursion_tail_stop:n {#1} +% \seq_gput_right:Nn \g_@@_name_stack_seq {#1} +% \@@_tmp:w +% } +%\exp_after:wN \@@_tmp:w \@currnamestack +% \q_recursion_tail \q_recursion_tail +% \q_recursion_tail \q_recursion_stop +% \end{macrocode} +% and finalle set the default label to be the \cs{@currname}: +% \begin{macrocode} +%\tl_gset:Nx \g_@@_hook_curr_name_tl { \@currname } +% \end{macrocode} % % Two commands keep track of the stack: when a file is input, -% \cs{@@_curr_name_push:n} pushes an (empty by default) label to the -% stack: +% \cs{@@_curr_name_push:n} pushes the current default label to the +% stack, and sets the new default label in one go: % \begin{macrocode} \cs_new_protected:Npn \@@_curr_name_push:n #1 + { \exp_args:Nx \@@_curr_name_push_aux:n { \@@_make_name:n {#1} } } +\cs_new_protected:Npn \@@_curr_name_push_aux:n #1 { - \seq_gpush:Nn \g_@@_name_stack_seq {#1} - \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} + \tl_if_blank:nTF {#1} + { \msg_error:nn { hooks } { no-default-label } } + { + \str_if_eq:nnTF {#1} { top-level } + { + \msg_error:nnnnn { hooks } { set-top-level } + { to } { PushDefaultHookLabel } {#1} + } + { + \seq_gpush:NV \g_@@_name_stack_seq \g_@@_hook_curr_name_tl + \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} + } + } } -% % \end{macrocode} % and when an input is over, the topmost item of the stack is popped, % since the label will not be used again, and \cs{g_@@_hook_curr_name_tl} @@ -3919,12 +4213,27 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_curr_name_pop: { - \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl - \seq_get:NNTF \g_@@_name_stack_seq \l_@@_return_tl + \seq_gpop:NNTF \g_@@_name_stack_seq \l_@@_return_tl { \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl } + { \msg_error:nn { hooks } { extra-pop-label } } + } +% \end{macrocode} +% +% At the end of the document we want to check if there was no +% \cs{@@_curr_name_push:} without a matching \cs{@@_curr_name_pop:} +% (not a critical error, but it might indicate that something else is +% not quite right): +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@after@enddocument@afterlastpage + { \@@_end_document_label_check: } +\cs_new_protected:Npn \@@_end_document_label_check: + { + \seq_gpop:NNT \g_@@_name_stack_seq \l_@@_return_tl { - \msg_error:nnn { hooks } { should-not-happen } - { Tried~to~pop~from~an~empty~default~label~stack. } + \msg_error:nnx { hooks } { missing-pop-label } + { \g_@@_hook_curr_name_tl } + \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl + \@@_end_document_label_check: } } % \end{macrocode} @@ -3935,14 +4244,69 @@ % Now define a wrapper that replaces the top of the stack with the % argument, and updates \cs{g_@@_hook_curr_name_tl} accordingly. % \begin{macrocode} +\NewDocumentCommand \SetDefaultHookLabel { m } + { + \seq_if_empty:NTF \g_@@_name_stack_seq + { + \msg_error:nnnnn { hooks } { set-top-level } + { for } { SetDefaultHookLabel } {#1} + } + { \exp_args:Nx \@@_set_default_label:n { \@@_make_name:n {#1} } } + } +\cs_new_protected:Npn \@@_set_default_label:n #1 + { + \str_if_eq:nnTF {#1} { top-level } + { + \msg_error:nnnnn { hooks } { set-top-level } + { to } { SetDefaultHookLabel } {#1} + } + { \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} } + } \NewDocumentCommand \DeclareDefaultHookLabel { m } { - \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl - \@@_curr_name_push:n {#1} + \msg_error:nn { hooks } { ddhl-deprecated } + \SetDefaultHookLabel {#1} + } +% \end{macrocode} +% +% The label is only automatically updated with \cs{@onefilewithoptions} +% (\cs{usepackage} and \cs{documentclass}), but some packages, like +% Ti\emph{k}Z, define package-like interfaces, like +% \cs{usetikzlibrary} that are wrappers around \cs{input}, so they +% inherit the default label currently in force (usually |top-level|, +% but it may change if loaded in another package). To provide a +% package-like behaviour also for hooks in these files, we provide +% high-level access to the default label stack. +% \begin{macrocode} +\NewDocumentCommand \PushDefaultHookLabel { m } + { \@@_curr_name_push:n {#1} } +\NewDocumentCommand \PopDefaultHookLabel { } + { \@@_curr_name_pop: } +% \end{macrocode} +% +% The current label stack holds the labels for all files but the +% current one (more or less like \cs{@currnamestack}), and the current +% label token list, \cs{g_@@_hook_curr_name_tl}, holds the label for +% the current file. However \cs{@pushfilename} happens before +% \cs{@currname} is set, so we need to look ahead to get the +% \cs{@currname} for the label. \pkg{expl3} also requires the current +% file in \cs{@pushfilename}, so here we abuse +% \cs{@expl@push@filename@aux@@@@} to do \cs{@@_curr_name_push:n}. +% \begin{macrocode} +\cs_gset_protected:Npn \@expl@push@filename@aux@@@@ #1#2#3 + { + \@@_curr_name_push:n {#3} + \str_gset:Nx \g_file_curr_name_str {#3} + #1 #2 {#3} } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % % @@ -4029,20 +4393,14 @@ % \end{macrocode} % % \begin{macro}{\@expl@@@initialize@all@@, -% \@expl@@@hook@curr@name@push@@n, % \@expl@@@hook@curr@name@pop@@} -% +% % \begin{macrocode} \cs_new_eq:NN \@expl@@@initialize@all@@ \__hook_initialize_all: % \end{macrocode} % % \begin{macrocode} -\cs_new_eq:NN \@expl@@@hook@curr@name@push@@n - \__hook_curr_name_push:n -% \end{macrocode} -% -% \begin{macrocode} \cs_new_eq:NN \@expl@@@hook@curr@name@pop@@ \__hook_curr_name_pop: % \end{macrocode} diff --git a/macros/latex/base/ltluatex.pdf b/macros/latex/base/ltluatex.pdf index e20118360c..7e559ecf45 100644 Binary files a/macros/latex/base/ltluatex.pdf and b/macros/latex/base/ltluatex.pdf differ diff --git a/macros/latex/base/ltmath.dtx b/macros/latex/base/ltmath.dtx index 36b8bb7ec4..770367c8a3 100644 --- a/macros/latex/base/ltmath.dtx +++ b/macros/latex/base/ltmath.dtx @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2020/07/27 v1.2g LaTeX Kernel (Math Setup)] + [2020/11/09 v1.2h LaTeX Kernel (Math Setup)] % \iffalse % % @@ -593,6 +593,13 @@ %\def\;{\mskip\thickmuskip} %\def\!{\mskip-\thinmuskip} % +% \end{macrocode} +% \changes{v1.2h}{2020/11/09}{\cs{negmedspace} and \cs{negthickspace} +% have been only in amsmath, so we need to undefine for rollback (gh/423)} +% \begin{macrocode} +%\let\negmedspace\@undefined +%\let\negthickspace\@undefined +% %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} diff --git a/macros/latex/base/ltmiscen.dtx b/macros/latex/base/ltmiscen.dtx index 9acbcccd68..cf7f3c836b 100644 --- a/macros/latex/base/ltmiscen.dtx +++ b/macros/latex/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2020/10/23 v1.1w LaTeX Kernel (Misc. Environments)] + [2020/12/18 v1.1x LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -277,17 +277,6 @@ % \end{macro} % \end{environment} % -% -% \begin{macro}{\@kernel@after@enddocument, -% \@kernel@after@enddocument@afterlastpage} -% -% The two kernel hooks above are used by the shipout code. -% \begin{macrocode} -\let\@kernel@after@enddocument\@empty -\let\@kernel@after@enddocument@afterlastpage\@empty -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\@enddocument@kernel@warnings} % % \begin{macrocode} @@ -395,8 +384,6 @@ % \endgroup % \deadcycles\z@\@@end} % -%\let\@kernel@after@enddocument\@undefined -%\let\@kernel@after@enddocument@afterlastpage\@undefined %\let\@enddocument@kernel@warnings\@undefined % %\EndIncludeInRelease diff --git a/macros/latex/base/ltnews.pdf b/macros/latex/base/ltnews.pdf index 902ff811d9..7da22f913b 100644 Binary files a/macros/latex/base/ltnews.pdf and b/macros/latex/base/ltnews.pdf differ diff --git a/macros/latex/base/ltnews01.pdf b/macros/latex/base/ltnews01.pdf index 8752885008..54c09ea91b 100644 Binary files a/macros/latex/base/ltnews01.pdf and b/macros/latex/base/ltnews01.pdf differ diff --git a/macros/latex/base/ltnews02.pdf b/macros/latex/base/ltnews02.pdf index a4dff175fa..cfbebec582 100644 Binary files a/macros/latex/base/ltnews02.pdf and b/macros/latex/base/ltnews02.pdf differ diff --git a/macros/latex/base/ltnews03.pdf b/macros/latex/base/ltnews03.pdf index b5cfd1312b..83b8cba6a6 100644 Binary files a/macros/latex/base/ltnews03.pdf and b/macros/latex/base/ltnews03.pdf differ diff --git a/macros/latex/base/ltnews04.pdf b/macros/latex/base/ltnews04.pdf index eff5873f9a..82f78370d2 100644 Binary files a/macros/latex/base/ltnews04.pdf and b/macros/latex/base/ltnews04.pdf differ diff --git a/macros/latex/base/ltnews05.pdf b/macros/latex/base/ltnews05.pdf index f963a2945a..a3a3ba2608 100644 Binary files a/macros/latex/base/ltnews05.pdf and b/macros/latex/base/ltnews05.pdf differ diff --git a/macros/latex/base/ltnews06.pdf b/macros/latex/base/ltnews06.pdf index ce4e6027fd..f08f189840 100644 Binary files a/macros/latex/base/ltnews06.pdf and b/macros/latex/base/ltnews06.pdf differ diff --git a/macros/latex/base/ltnews07.pdf b/macros/latex/base/ltnews07.pdf index 29e99ec882..c44afe8b77 100644 Binary files a/macros/latex/base/ltnews07.pdf and b/macros/latex/base/ltnews07.pdf differ diff --git a/macros/latex/base/ltnews08.pdf b/macros/latex/base/ltnews08.pdf index 9a29dfdc01..575c90644e 100644 Binary files a/macros/latex/base/ltnews08.pdf and b/macros/latex/base/ltnews08.pdf differ diff --git a/macros/latex/base/ltnews09.pdf b/macros/latex/base/ltnews09.pdf index 3792d6944e..938671e92b 100644 Binary files a/macros/latex/base/ltnews09.pdf and b/macros/latex/base/ltnews09.pdf differ diff --git a/macros/latex/base/ltnews10.pdf b/macros/latex/base/ltnews10.pdf index 08f4794fb0..1b065aff91 100644 Binary files a/macros/latex/base/ltnews10.pdf and b/macros/latex/base/ltnews10.pdf differ diff --git a/macros/latex/base/ltnews11.pdf b/macros/latex/base/ltnews11.pdf index 47d305bb00..b5dbd3f722 100644 Binary files a/macros/latex/base/ltnews11.pdf and b/macros/latex/base/ltnews11.pdf differ diff --git a/macros/latex/base/ltnews12.pdf b/macros/latex/base/ltnews12.pdf index 353e08f72f..103e8b18e3 100644 Binary files a/macros/latex/base/ltnews12.pdf and b/macros/latex/base/ltnews12.pdf differ diff --git a/macros/latex/base/ltnews13.pdf b/macros/latex/base/ltnews13.pdf index 9f04262286..0041691329 100644 Binary files a/macros/latex/base/ltnews13.pdf and b/macros/latex/base/ltnews13.pdf differ diff --git a/macros/latex/base/ltnews14.pdf b/macros/latex/base/ltnews14.pdf index 07bf87f377..2bc925c555 100644 Binary files a/macros/latex/base/ltnews14.pdf and b/macros/latex/base/ltnews14.pdf differ diff --git a/macros/latex/base/ltnews15.pdf b/macros/latex/base/ltnews15.pdf index 48d7b278e4..820600a8df 100644 Binary files a/macros/latex/base/ltnews15.pdf and b/macros/latex/base/ltnews15.pdf differ diff --git a/macros/latex/base/ltnews16.pdf b/macros/latex/base/ltnews16.pdf index 86bce9ff9b..3c4336dd45 100644 Binary files a/macros/latex/base/ltnews16.pdf and b/macros/latex/base/ltnews16.pdf differ diff --git a/macros/latex/base/ltnews17.pdf b/macros/latex/base/ltnews17.pdf index 4c4edcce1d..cecb7a07dc 100644 Binary files a/macros/latex/base/ltnews17.pdf and b/macros/latex/base/ltnews17.pdf differ diff --git a/macros/latex/base/ltnews18.pdf b/macros/latex/base/ltnews18.pdf index dbad7935b3..494f0fa0ec 100644 Binary files a/macros/latex/base/ltnews18.pdf and b/macros/latex/base/ltnews18.pdf differ diff --git a/macros/latex/base/ltnews19.pdf b/macros/latex/base/ltnews19.pdf index 254e795808..2c4a3b518a 100644 Binary files a/macros/latex/base/ltnews19.pdf and b/macros/latex/base/ltnews19.pdf differ diff --git a/macros/latex/base/ltnews20.pdf b/macros/latex/base/ltnews20.pdf index 96ec4b6137..b1e5c67560 100644 Binary files a/macros/latex/base/ltnews20.pdf and b/macros/latex/base/ltnews20.pdf differ diff --git a/macros/latex/base/ltnews21.pdf b/macros/latex/base/ltnews21.pdf index 5829c7a022..eb0264792c 100644 Binary files a/macros/latex/base/ltnews21.pdf and b/macros/latex/base/ltnews21.pdf differ diff --git a/macros/latex/base/ltnews22.pdf b/macros/latex/base/ltnews22.pdf index 8a6b871ce8..ddfb6d3d3a 100644 Binary files a/macros/latex/base/ltnews22.pdf and b/macros/latex/base/ltnews22.pdf differ diff --git a/macros/latex/base/ltnews23.pdf b/macros/latex/base/ltnews23.pdf index 518555e784..a32e1efbb4 100644 Binary files a/macros/latex/base/ltnews23.pdf and b/macros/latex/base/ltnews23.pdf differ diff --git a/macros/latex/base/ltnews24.pdf b/macros/latex/base/ltnews24.pdf index 11210010a2..6dc47bb3de 100644 Binary files a/macros/latex/base/ltnews24.pdf and b/macros/latex/base/ltnews24.pdf differ diff --git a/macros/latex/base/ltnews25.pdf b/macros/latex/base/ltnews25.pdf index 4965241eec..82908a28f2 100644 Binary files a/macros/latex/base/ltnews25.pdf and b/macros/latex/base/ltnews25.pdf differ diff --git a/macros/latex/base/ltnews26.pdf b/macros/latex/base/ltnews26.pdf index 9af3fd445a..604db55709 100644 Binary files a/macros/latex/base/ltnews26.pdf and b/macros/latex/base/ltnews26.pdf differ diff --git a/macros/latex/base/ltnews27.pdf b/macros/latex/base/ltnews27.pdf index 1359bc7efc..472ea7679f 100644 Binary files a/macros/latex/base/ltnews27.pdf and b/macros/latex/base/ltnews27.pdf differ diff --git a/macros/latex/base/ltnews28.pdf b/macros/latex/base/ltnews28.pdf index f5cb87308b..14ef2d02dd 100644 Binary files a/macros/latex/base/ltnews28.pdf and b/macros/latex/base/ltnews28.pdf differ diff --git a/macros/latex/base/ltnews29.pdf b/macros/latex/base/ltnews29.pdf index 5d618bc87e..e8197be1b3 100644 Binary files a/macros/latex/base/ltnews29.pdf and b/macros/latex/base/ltnews29.pdf differ diff --git a/macros/latex/base/ltnews30.pdf b/macros/latex/base/ltnews30.pdf index 35846d4fc9..920d022e99 100644 Binary files a/macros/latex/base/ltnews30.pdf and b/macros/latex/base/ltnews30.pdf differ diff --git a/macros/latex/base/ltnews31.pdf b/macros/latex/base/ltnews31.pdf index f0778f9d30..6a62e97123 100644 Binary files a/macros/latex/base/ltnews31.pdf and b/macros/latex/base/ltnews31.pdf differ diff --git a/macros/latex/base/ltnews32.pdf b/macros/latex/base/ltnews32.pdf index aed46fe573..93536d352a 100644 Binary files a/macros/latex/base/ltnews32.pdf and b/macros/latex/base/ltnews32.pdf differ diff --git a/macros/latex/base/ltshipout-code.pdf b/macros/latex/base/ltshipout-code.pdf index c5cfd30a88..f95e0ebf75 100644 Binary files a/macros/latex/base/ltshipout-code.pdf and b/macros/latex/base/ltshipout-code.pdf differ diff --git a/macros/latex/base/ltshipout-doc.pdf b/macros/latex/base/ltshipout-doc.pdf index 6a4b41f60e..074774312a 100644 Binary files a/macros/latex/base/ltshipout-doc.pdf and b/macros/latex/base/ltshipout-doc.pdf differ diff --git a/macros/latex/base/ltshipout.dtx b/macros/latex/base/ltshipout.dtx index 8f0422c887..e226f753f3 100644 --- a/macros/latex/base/ltshipout.dtx +++ b/macros/latex/base/ltshipout.dtx @@ -31,8 +31,8 @@ %%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v1.0c} -\providecommand\ltshipoutdate{2020/09/27} +\providecommand\ltshipoutversion{v1.0d} +\providecommand\ltshipoutdate{2020/11/24} % \end{macrocode} % %<*driver> @@ -1376,9 +1376,11 @@ % % % \begin{macro}{\AtBeginDvi} -% +% If we roll forward from an earlier kernel \cs{AtBeginDvi} is +% defined so we better not use \cs{cs_new_protected:Npn} here. +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} % \begin{macrocode} -\cs_new_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} +\cs_set_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} % \end{macrocode} % \end{macro} % @@ -1448,7 +1450,17 @@ % \begin{macrocode} %\IncludeInRelease{0000/00/00}% % {\shipout}{The hook management (shipout)}% -%\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname +% +% \end{macrocode} +% If we roll forward then \cs{tex\_shipout:D} may not be defined in +% which case \cs{shipout} does have it original definition and so +% we must not \cs{let} it to something else which is \cs{relax}! +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\ifcsname tex_shipout:D\endcsname +%\expandafter\let\expandafter\shipout +% \csname tex_shipout:D\endcsname +%\fi % %\let \ShipoutBox\@undefined %\let \ReadonlyShipoutCounter \@undefined diff --git a/macros/latex/base/ltvers.dtx b/macros/latex/base/ltvers.dtx index dd69d5a6e3..c2ec2ffde3 100644 --- a/macros/latex/base/ltvers.dtx +++ b/macros/latex/base/ltvers.dtx @@ -115,7 +115,7 @@ {2020-10-01} % %<*2ekernel> -\def\patch@level{2} +\def\patch@level{3} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/macros/latex/base/ltx3info.pdf b/macros/latex/base/ltx3info.pdf index 620a9b2c6f..070c822a17 100644 Binary files a/macros/latex/base/ltx3info.pdf and b/macros/latex/base/ltx3info.pdf differ diff --git a/macros/latex/base/ltxdoc.pdf b/macros/latex/base/ltxdoc.pdf index 5080c0e0bc..e5d6fb99cf 100644 Binary files a/macros/latex/base/ltxdoc.pdf and b/macros/latex/base/ltxdoc.pdf differ diff --git a/macros/latex/base/makeindx.pdf b/macros/latex/base/makeindx.pdf index 97b26b4e72..7993372c01 100644 Binary files a/macros/latex/base/makeindx.pdf and b/macros/latex/base/makeindx.pdf differ diff --git a/macros/latex/base/manual.pdf b/macros/latex/base/manual.pdf index 0958c15eb6..50811f5d4c 100644 Binary files a/macros/latex/base/manual.pdf and b/macros/latex/base/manual.pdf differ diff --git a/macros/latex/base/modguide.pdf b/macros/latex/base/modguide.pdf index 7dafc9125a..5f51237557 100644 Binary files a/macros/latex/base/modguide.pdf and b/macros/latex/base/modguide.pdf differ diff --git a/macros/latex/base/nfssfont.pdf b/macros/latex/base/nfssfont.pdf index 8292894e71..8f189189d9 100644 Binary files a/macros/latex/base/nfssfont.pdf and b/macros/latex/base/nfssfont.pdf differ diff --git a/macros/latex/base/proc.pdf b/macros/latex/base/proc.pdf index a046c4fbfa..35ba9262e0 100644 Binary files a/macros/latex/base/proc.pdf and b/macros/latex/base/proc.pdf differ diff --git a/macros/latex/base/slides.pdf b/macros/latex/base/slides.pdf index 37779f807a..b4d275289c 100644 Binary files a/macros/latex/base/slides.pdf and b/macros/latex/base/slides.pdf differ diff --git a/macros/latex/base/slifonts.pdf b/macros/latex/base/slifonts.pdf index 67f44b6017..39952e8a88 100644 Binary files a/macros/latex/base/slifonts.pdf and b/macros/latex/base/slifonts.pdf differ diff --git a/macros/latex/base/source2e.pdf b/macros/latex/base/source2e.pdf index bc06f27f18..106d83f723 100644 Binary files a/macros/latex/base/source2e.pdf and b/macros/latex/base/source2e.pdf differ diff --git a/macros/latex/base/source2edoc.cls b/macros/latex/base/source2edoc.cls index 5b6700039c..e06108230d 100644 --- a/macros/latex/base/source2edoc.cls +++ b/macros/latex/base/source2edoc.cls @@ -2,7 +2,7 @@ % This class is buggy and needs fixing \ProvidesClass{source2edoc} - [2020/08/16 v0.1 Quick hack to typeset source2.tex + [2020/12/02 v0.2 Quick hack to typeset source2.tex (not usable for anything else and buggy -- will vanish again)!] \LoadClass{l3doc} @@ -14,8 +14,43 @@ -% l3doc's def are buggy (already fixed there but not distributed yet) + \ExplSyntaxOn + +% in 2e we have a lot of functions that have no ``user-level'' documentation so we disable +% a bogus backref in that case. Over time the sources should be clean up to have such documentation. + +\cs_set_protected:Npn \__codedoc_print_documented: + { + \seq_gset_filter:NNn \g__codedoc_nested_names_seq + \g__codedoc_nested_names_seq + { ! \__codedoc_if_macro_internal_p:n {##1} } + \seq_if_empty:NF \g__codedoc_nested_names_seq + { +% This is a crude change: we grab the first name + \__codedoc_get_hyper_target:xN + { \seq_item:Nn \g__codedoc_nested_names_seq { 1 } } + \l__codedoc_tmpa_tl +% ... and check if it has a reference + \cs_if_exist:cT{ r@\l__codedoc_tmpa_tl } +% If it does we show it, if not we don't. + { + \int_set:Nn \l__codedoc_tmpa_int + { \seq_count:N \g__codedoc_nested_names_seq } + \int_compare:nNnTF \l__codedoc_tmpa_int = 1 {~This~} {~These~} + \bool_if:NTF \l__codedoc_macro_var_bool {variable} {function} + \int_compare:nNnTF \l__codedoc_tmpa_int = 1 {~is~} {s~are~} + documented~on~page~ + \exp_args:Nx \pageref { \l__codedoc_tmpa_tl } . + } + } + \seq_gclear:N \g__codedoc_nested_names_seq + } + + + +% some l3doc's def are buggy (already fixed there but not distributed yet) + \RenewDocumentCommand \DocInclude { m } { \relax\clearpage diff --git a/macros/latex/base/syntonly.pdf b/macros/latex/base/syntonly.pdf index c13cc82d80..1493490c91 100644 Binary files a/macros/latex/base/syntonly.pdf and b/macros/latex/base/syntonly.pdf differ diff --git a/macros/latex/base/tlc2.pdf b/macros/latex/base/tlc2.pdf index 03eec97dc7..0c08e372a3 100644 Binary files a/macros/latex/base/tlc2.pdf and b/macros/latex/base/tlc2.pdf differ diff --git a/macros/latex/base/tulm.pdf b/macros/latex/base/tulm.pdf index e67d8d3522..d480c33dff 100644 Binary files a/macros/latex/base/tulm.pdf and b/macros/latex/base/tulm.pdf differ diff --git a/macros/latex/base/usrguide.pdf b/macros/latex/base/usrguide.pdf index 96de459ec3..51412a147a 100644 Binary files a/macros/latex/base/usrguide.pdf and b/macros/latex/base/usrguide.pdf differ diff --git a/macros/latex/base/utf8ienc.pdf b/macros/latex/base/utf8ienc.pdf index e97c6a4527..00da2138cd 100644 Binary files a/macros/latex/base/utf8ienc.pdf and b/macros/latex/base/utf8ienc.pdf differ diff --git a/macros/latex/base/webcomp.pdf b/macros/latex/base/webcomp.pdf index a6b1e79980..1c36db0c61 100644 Binary files a/macros/latex/base/webcomp.pdf and b/macros/latex/base/webcomp.pdf differ diff --git a/macros/latex/contrib/biblatex/CHANGES.md b/macros/latex/contrib/biblatex/CHANGES.md index 5de6bc5994..7a035b5a3e 100644 --- a/macros/latex/contrib/biblatex/CHANGES.md +++ b/macros/latex/contrib/biblatex/CHANGES.md @@ -1,3 +1,23 @@ +# RELEASE NOTES FOR VERSION 3.16 +- Fixed an infinite loop caused by excessive aliasing of the `volcitepages` + format. + Reverted the alias `\DeclareFieldAlias{volcitepages}{postnote}` + and again define + ``` + \DeclareFieldFormat{volcitepages}{\mkpageprefix[pagination][\mknormrange]{#1}} + ``` + explicitly. +- Fixed `.lbx` file loading behaviour. All `.lbx` files are now loaded + `\AtBeginDocument`. Languages that were not requested explicitly by packages + are recorded in the `.aux` file and loaded on the next run. + This may require a further LaTeX run in some situations, but now we can be + sure when `.lbx` files are read. +- Added `label` option to `\printbibliography`. +- Added more name wrapper aliases to make name aliasing smoother. +- Deprecate `\mainlang` switch in favour of the text macro `\textmainlang`. +- Deprecate `\mkrelatedstring` (which is defined as `\mainlang`) + in favour of `\mkrelatestringtext` (defined as `\textmainlang`). + # RELEASE NOTES FOR VERSION 3.15a - Fixed bug with long argument for `\DeclareFieldFormat` and friends. @@ -35,6 +55,10 @@ \DeclareFieldFormat{multiprenote}{#1\isdot} \DeclareFieldFormat{multipostnote}{\mkpageprefix[pagination][\mknormrange]{#1}} ``` + + **NB** The definition of `volcitepages` caused an infinite loop and was + reverted in v3.15b. + This means that only `multiprenote` and `multipostnote` are aliased. - Unified DOI, eprint and URL printing across all entry types. The fields `doi`, `eprint`, `eprintclass`, `eprinttype` and `url` are now valid for all entry types. @@ -453,7 +477,7 @@ Since `\mknormrange` acts only on page ranges as detected by `\ifpages`, this does not affect text other than page ranges. Hyphens and dashes in page ranges will be transformed to - `\bibrangedash`, commas and semi-colons to `\bibrangesep`. + `\bibrangedash`, commas and semicolons to `\bibrangesep`. This is analogous to Biber's treatment of page-like fields. If you always separated page ranges with `--` or `\bibrangedash` anyway, this should not change the output you get. diff --git a/macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst b/macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst index dc1837f941..8e5103a458 100644 --- a/macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst +++ b/macros/latex/contrib/biblatex/bibtex/bst/biblatex.bst @@ -184,7 +184,7 @@ STRINGS { ctrl.alphaothers ctrl.sortalphaothers ctrl.sortstr last.name last.hash last.year last.extra } FUNCTION {initialize} { - "$Revision: 3.15 $" + "$Revision: 3.16 $" #12 entry.max$ substring$ #-3 entry.max$ substring$ "Biblatex version: " swap$ * top$ diff --git a/macros/latex/contrib/biblatex/doc/biblatex.pdf b/macros/latex/contrib/biblatex/doc/biblatex.pdf index c50f7bb304..3944dda3ff 100644 Binary files a/macros/latex/contrib/biblatex/doc/biblatex.pdf and b/macros/latex/contrib/biblatex/doc/biblatex.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/biblatex.tex b/macros/latex/contrib/biblatex/doc/biblatex.tex index 87e406158a..618c5ac60f 100644 --- a/macros/latex/contrib/biblatex/doc/biblatex.tex +++ b/macros/latex/contrib/biblatex/doc/biblatex.tex @@ -64,7 +64,7 @@ url={\biblatexhome}, author={Philip Kime, Moritz Wemheuer, Philipp Lehman}, email={}, - revision={3.15a}, + revision={3.16}, date={\today}} \hypersetup{% @@ -200,6 +200,7 @@ Boruvka and Joseph Wright who helped with the transition of ownership in 2012 and following years. The language modules of this package are made possible thanks to the following contributors:\\ +Ander Zarketa-Astigarraga (Basque); Augusto Ritter Stoffel, Mateus Araújo, Gustavo Barros (Brazilian); Kaloyan Ganev (Bulgarian); Sebastià Vila-Marta (Catalan); @@ -1252,6 +1253,7 @@ The gender of the author or the gender of the editor, if there is no author. The \multicolumn{1}{@{}H}{Region/Dialect} & \multicolumn{1}{@{}H}{Identifiers} \\ \cmidrule(r){1-1}\cmidrule(r){2-2}\cmidrule{3-3} +Basque & France, Spain & \opt{basque} \\ Bulgarian & Bulgaria & \opt{bulgarian} \\ Catalan & Spain, France, Andorra, Italy & \opt{catalan} \\ Croatian & Croatia, Bosnia and Herzegovina, Serbia & \opt{croatian} \\ @@ -2076,7 +2078,7 @@ Loads a citation module which provides \sty{mcite}\slash\sty{mciteplus}-like cit \optitem[auto]{casechanger}{\opt{auto}, \opt{latex2e}, \opt{expl3}} -This option selects the implementation of \biblatex's case changing functions, most prominently \cmd{MakeSentenceCase*}. \opt{expl3} selects the new implementation based on the \latex3 module \sty{l3text}. \opt{latex2e} selects the original implementation, which has tricky brace protection behaviour and some shortcomings when dealing with non-ASCII characters. The default \opt{auto} selects the case changing code based on the available \sty{expl3} version (\opt{expl3} is selected if \sty{expl3} is at least version 2020-04-06). +This option selects the implementation of \biblatex's case changing functions, most prominently \cmd{MakeSentenceCase*}. \opt{expl3} selects the new implementation based on the \latex3 module \sty{l3text}. Note that the \sty{l3text} module assumes \utf input and that your \sty{expl3} version should be new enough (at least version 2020-04-06). \opt{latex2e} selects the original implementation, which has tricky brace protection behaviour and some shortcomings when dealing with non-ASCII characters. The default \opt{auto} selects the case changing code based on the available \sty{expl3} version and detected document encoding (\opt{expl3} is selected if \sty{expl3} is at least version 2020-04-06 and the document encoding is detected as \utf). \end{optionlist} @@ -3098,7 +3100,7 @@ Whether the default data model name part (von, van, of, da, de, della, \end{itemize} % For example, if this option is enabled, \biblatex precedes the family name with the prefix---Ludwig van Beethoven would be cited as «van Beethoven» and alphabetized as «Van Beethoven, Ludwig». If this option is disabled (the default), he is cited as «Beethoven» and alphabetized as «Beethoven, Ludwig van» instead. -This option is also settable on a per-type scope. With \biblatexml datasources and the \bibtex extended name format supported by \biber, this is also settable on per-namelist and per-name scopes. +This option is also settable on a per-type scope. With \biblatexml datasources and the \bibtex extended name format supported by \biber (see \secref{use:enf}), this is also settable on per-namelist and per-name scopes. \optitem{indexing}{\opt{true}, \opt{false}, \opt{cite}, \opt{bib}} @@ -3309,6 +3311,64 @@ This style prints all bibliographic data in tabular format. It is intended for d \end{marglist} +\subsection{Extended Name Format} +\label{use:enf} +The parsing rules for \bibtex names are rather archaic and not suited to +many international name formats. \biber supports an extended name format +which allows explicit specification of the parts of names. This allows the +use of custom name parts apart from the four standard \bibtex parts. Extended +name formats are supported in all name fields and can be used along with +the usual \bibtex name format. Recognition of extended name format can be +disabled with the \biber option \opt{--noxname} in case you do not need the +extended format and the auto-detection causes problems with normal name +parsing. The separator \verb+=+ which comes between the namepart names and +values is customisable with the \biber option \opt{--xnamesep}. Here is an +example: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {Hans Harman and Simon de Beumont} +AUTHOR = {given=Hans, family=Harman and given=Simon, prefix=de, family=Beumont} +\end{lstlisting} +% +These two name specifications are equivalent but the extended format +explicitly names the parts. The supported parts are those specified by the +\biblatex data mode constant \opt{nameparts}, see \secref{aut:bbx:drv}. As +with traditional \bibtex name parsing, initials are automatically generated +but it is also possible to specify these explicitly: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {given=Jean, prefix=de la, prefix-i=d, family=Rousse} +AUTHOR = {given={Jean Pierre Simon}, given-i=JPS} +\end{lstlisting} +% +Initials are specified by adding the suffix \verb+-i+ to the namepart name. +Compound parts may be protected with braces: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {given={Jean Pierre}} +\end{lstlisting} +% +If a namepart contains a comma, the whole namepart should be protected with +quotes: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {"family={Robert and Sons, Inc.}"} +\end{lstlisting} +% +Traditional \bibtex name formats and the extended form may be used together: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {Hans Harman and given=Simon, prefix=de, family=Beumont} +\end{lstlisting} +% +Per-namelist and per-name options may be specified in the extended name +format, see \secref{use:opt:bib:hyb}: + +\begin{lstlisting}[style=bibtex]{} +AUTHOR = {nosortothers=true and Hans Harman and + given=Simon, family=Beumont, prefix=de, useprefix=true} +\end{lstlisting} + \subsection{Related Entries} \label{use:rel} @@ -3444,7 +3504,7 @@ The format of annotation fields in \bibtex data sources is is as follows: ::= ["] (string) ["] \end{lstlisting} % -That is, one or more specifications separated by semi-colons. Each specification is an equals sign followed by a comma"=separated list of annotation keywords or a string enclosed in double-quotes (a annotation, see below). To annotate a specific item in a list, put the number of the list item before the equals sign (lists start at 1). If you need to annotate a specific part of the list item, give its name after the list item number, preceded by a colon. Name part names are defined in the data model, see \secref{aut:bbx:drv}. Some further examples: +That is, one or more specifications separated by semicolons. Each specification is an equals sign followed by a comma"=separated list of annotation keywords or a string enclosed in double-quotes (a annotation, see below). To annotate a specific item in a list, put the number of the list item before the equals sign (lists start at 1). If you need to annotate a specific part of the list item, give its name after the list item number, preceded by a colon. Name part names are defined in the data model, see \secref{aut:bbx:drv}. Some further examples: \begin{lstlisting}[style=bibtex]{} AUTHOR = {Last1, First1 and Last2, First2 and Last3, First3}, @@ -3616,7 +3676,7 @@ Adds a \prm{resource}, such as a \file{.bib} file, to the default resource list. \addbibresource[glob]{bibfiles/bibfile*.bib} \addbibresource[glob]{bibfile-num?.bib} \addbibresource[glob]{bibfile{1,2,3}.bib} -\addbibresource[location=remote]{http://www.citeulike.org/bibtex/group/9517} +\addbibresource[location=remote]{https://raw.githubusercontent.com/plk/biblatex/master/bibtex/bib/biblatex/biblatex-examples.bib} \addbibresource[location=remote,label=lan]{ftp://192.168.1.57/~user/file.bib} \end{ltxexample} % @@ -3696,6 +3756,10 @@ The bibliography and the list of shorthands typically have a chapter or section This option overrides the default title provided by the heading selected with the \opt{heading} option, if supported by the heading definition. See \secref{use:bib:hdg} for details. +\valitem{label}{label} + +If \prm{label} is nonempty, issue \texttt{\textbackslash label\{\prm{label}\}} after typesetting the heading. No sanity checking is done whether or not it is useful to set a label after the heading (\eg if the heading is not numbered a \texttt{\textbackslash ref} to the label might not result in useful output). + \optitem[\normalfont\emph{global setting} (\opt{none})]{block}{\opt{none}, \opt{space}, \opt{par}, \opt{nbpar}, \opt{ragged}} This option overrides the global \opt{block} option (see \secref{use:opt:pre:gen}, the meaning of the settings is explained there as well). @@ -3786,7 +3850,7 @@ This command loops over all bibliography categories. This is equivalent to givin \cmditem{printbibheading}[key=value, \dots] -This command prints a bibliography heading defined with \cmd{defbibheading}. It takes one optional argument, which is a list of options given in \keyval notation. The options are a small subset of those supported by \cmd{printbibliography}. Valid options are \opt{heading} and \opt{title}. By default, this command uses the heading \texttt{bibliography}. See \secref{use:bib:hdg} for details. Also see \secref{use:use:mlt,use:use:div} for usage examples. +This command prints a bibliography heading defined with \cmd{defbibheading}. It takes one optional argument, which is a list of options given in \keyval notation. The options are a small subset of those supported by \cmd{printbibliography}. Valid options are \opt{heading}, \opt{title} and \opt{label}. By default, this command uses the heading \texttt{bibliography}. See \secref{use:bib:hdg} for details. Also see \secref{use:use:mlt,use:use:div} for usage examples. \cmditem{DeclarePrintbibliographyDefaults}{key=value, \dots} @@ -4330,7 +4394,7 @@ At the beginning of the document, there is always a global context containing gl \cmditem{assignrefcontextentries*}[key=value, \dots]{*} \end{ltxsyntax} -These commands automate putting citations into refcontexts when the default behaviour is not sufficient. The \prm{key=value} options are as for \cmd{DeclareRefcontext}. The default behaviour is that the data for a citation is drawn from the refcontext of the most recently processed bibliography in which it was printed\footnote{This does not always mean what one might think. In a document containing multiple bibliographies, the last bibliography will be the context for any citations \emph{before} the first bibliography because all bibliographies are processed when the \file{.bbl} is read.}. For citations that are used in some way but not printed in a bibliography or bibliography list, they default to drawing their data from the global refcontext established at the beginning of the document. To override this behaviour, instead of manually wrapping citation commands in \env{refcontext} environments, which might be error-prone and tedious, you can register a comma"=separated list of \prm{keywords}, \prm{categories} or \prm{entrykeys} which, respectively, make the entries with any of the specified keywords, entries in any of the specified categories (see \secref{use:use:div}) or entries with any of the specified citation keys draw their data from a particular refcontext specified by the \prm{refcontext key/values} which are parsed as the per the corresponding \env{refcontext} options. Such refcontext auto-assignments are specific to the current refsection. You may specify the same citation key in any of these commands but be aware that assignment is done in the order \prm{keywords}, \prm{categories}, \prm{entrykeys} with the later specifications overriding the earlier. \cmd{assignrefcontextentries} accepts a single asterisk instead of a list of entrykeys which allows the assignment of all keys in a refsection to a refcontext with having to explicitly list them. An example: +These commands automate putting citations into refcontexts when the default behaviour is not sufficient. The \prm{key=value} options are as for \cmd{DeclareRefcontext} with the addition of the \kvopt{name}{refcontextname} option which sets all options from those defined for the named refcontext \prm{refcontextname}. Use \kvopt{name}{default} to use the global default refcontext options. The specific \keyval options override those set by any named \prm{refcontextname}. The default behaviour is that the data for a citation is drawn from the refcontext of the most recently processed bibliography in which it was printed\footnote{This does not always mean what one might think. In a document containing multiple bibliographies, the last bibliography will be the context for any citations \emph{before} the first bibliography because all bibliographies are processed when the \file{.bbl} is read.}. For citations that are used in some way but not printed in a bibliography or bibliography list, they default to drawing their data from the global refcontext established at the beginning of the document. To override this behaviour, instead of manually wrapping citation commands in \env{refcontext} environments, which might be error-prone and tedious, you can register a comma"=separated list of \prm{keywords}, \prm{categories} or \prm{entrykeys} which, respectively, make the entries with any of the specified keywords, entries in any of the specified categories (see \secref{use:use:div}) or entries with any of the specified citation keys draw their data from a particular named refcontext and/or specified \prm{refcontext key/values}. Such refcontext auto-assignments are specific to the current refsection. You may specify the same citation key in any of these commands but be aware that assignment is done in the order \prm{keywords}, \prm{categories}, \prm{entrykeys} with the later specifications overriding the earlier. \cmd{assignrefcontextentries} accepts a single asterisk instead of a list of entrykeys which allows the assignment of all keys in a refsection to a refcontext with having to explicitly list them. An example: \begin{ltxexample}[style=latex] \assignrefcontextentries[labelprefix=A]{key2} @@ -4353,6 +4417,28 @@ The starred versions do not override a local refcontext and so with: % the data for the citation of \bibfield{key2} will be drawn from refcontext \opt{labelprefix=B}. Note that these commands are rarely necessary unless you have multiple bibliographies in which the same citations occur and \biblatex\ cannot by default tell which bibliography list a citation should refer to. See the example file \file{94-labelprefix.tex} for more details. +\begin{ltxexample}[style=latex] +\DeclareRefcontext{testrc}{labelprefix=A} +\assignrefcontextentries[name=testrc]{key2} +\cite{key1} +\begin{refcontext}[labelprefix=B] +\cite{key2} +\end{refcontext} +\end{ltxexample} +% +Here, the data for the citation of \bibfield{key2} will be drawn from the refcontext named which has \opt{labelprefix=A} and not \opt{labelprefix=B} (resulting in a label with prefix and not ). + +\begin{ltxexample}[style=latex] +\DeclareRefcontext{testrc}{labelprefix=A} +\assignrefcontextentries[name=testrc,labelprefix=C]{key2} +\cite{key1} +\begin{refcontext}[labelprefix=B] +\cite{key2} +\end{refcontext} +\end{ltxexample} +% +Here, the data for the citation of \bibfield{key2} will be drawn from refcontext with \opt{labelprefix=C} and not \opt{labelprefix=A} since the explicit options override the named refcontext (resulting in a label with prefix and not or ). + \subsubsection{Dynamic Entry Sets} \label{use:bib:set} @@ -4727,7 +4813,7 @@ Similar to \cmd{psq} but indicates an open-ended page range. See \secref{use:cav \cmditem{pnfmt}{text} -This command formats is argument \prm{text} in the same format as \bibfield{postnote}. The command can be used to format a page range while adding additional text in the postnote argument of a cite command. +This command formats its argument \prm{text} in the same format as \bibfield{postnote}. The command can be used to format a page range while adding additional text in the postnote argument of a cite command. \begin{ltxexample} \autocite[\pnfmt{378-381, 383} and more]{sigfridsson} @@ -6732,7 +6818,7 @@ Names depend on the datamodel constant which has the default definit {prefix,family,suffix,given} \end{ltxexample} % -This can be customised to add more name parts to deal with things like patronymics (see the example file \file{93-nameparts.tex}). This needs an extended name format for data sources since the standard \bibtex name format is very limited. \biblatexml (\secref{apx:biblatexml}) handles this natively and there is an extended name format which can handle custom nameparts when using \biber (see \biber documentation). +This can be customised to add more name parts to deal with things like patronymics (see the example file \file{93-nameparts.tex}). This needs an extended name format for data sources since the standard \bibtex name format is very limited. \biblatexml (\secref{apx:biblatexml}) handles this natively and there is an extended name format which can handle custom nameparts when using \biber (see \secref{use:enf}). Inside name formats, the constant declaration makes available two or three macros for each name part defined in the datamodel: @@ -9355,7 +9441,7 @@ or just a name list by using the option as a pseudo-name which will be ignored: \end{lstlisting} % or just a single name by passing the option as part of the extended name information -format which \biber supports (see \biber doc): +format which \biber supports (see \secref{use:enf}): \begin{lstlisting}[style=bibtex]{} @BOOK{key, @@ -10811,7 +10897,7 @@ The pagination strings are taken from \texttt{$<$pagination$>$total} and \texttt \cmditem{mkcomprange}[postpro][itempostpro]{text} \cmditem*{mkcomprange*}[postpro][itempostpro]{text} -This command, which is intended for use in field formatting directives, will parse its \prm{text} argument for page ranges and compress them. For example, «125--129» may be formatted as «125--9». You may configure the behavior of \cmd{mkcomprange} by adjusting the \latex counters \cnt{mincomprange}, \cnt{maxcomprange}, and \cnt{mincompwidth}, as illustrated in \tabref{aut:aux:tab1}. The default settings are \texttt{10}, \texttt{100000}, and \texttt{1}, respectively. This means that the command tries to compress as much as possible by default. Use \cmd{setcounter} to adjust the parameters. The scanner recognises \cmd{bibrangedash} and hyphens as range dashes. It will normalize the dash by replacing any number of consecutive hyphens with \cmd{bibrangedash}. Lists of ranges delimited with \cmd{bibrangessep} are also supported. The scanner will normalise any comma or semi-colons surrounded by optional space by replacing them with \cmd{bibrangessep}. If you want to hide a character from the list/range scanner for some reason, wrap the character or the entire string in curly braces. The optional \prm{postpro} argument specifies a macro to be used for post-processing the \prm{text}. This is important if you want to combine \cmd{mkcomprange} with other formatting macros which also need to parse their \prm{text} argument, such as \cmd{mkpageprefix}. Simply nesting these commands will not work as expected. Use the \prm{postpro} argument to set up the processing chain as follows: +This command, which is intended for use in field formatting directives, will parse its \prm{text} argument for page ranges and compress them. For example, «125--129» may be formatted as «125--9». You may configure the behavior of \cmd{mkcomprange} by adjusting the \latex counters \cnt{mincomprange}, \cnt{maxcomprange}, and \cnt{mincompwidth}, as illustrated in \tabref{aut:aux:tab1}. The default settings are \texttt{10}, \texttt{100000}, and \texttt{1}, respectively. This means that the command tries to compress as much as possible by default. Use \cmd{setcounter} to adjust the parameters. The scanner recognises \cmd{bibrangedash} and hyphens as range dashes. It will normalize the dash by replacing any number of consecutive hyphens with \cmd{bibrangedash}. Lists of ranges delimited with \cmd{bibrangessep} are also supported. The scanner will normalise any comma or semicolons surrounded by optional space by replacing them with \cmd{bibrangessep}. If you want to hide a character from the list/range scanner for some reason, wrap the character or the entire string in curly braces. The optional \prm{postpro} argument specifies a macro to be used for post-processing the \prm{text}. This is important if you want to combine \cmd{mkcomprange} with other formatting macros which also need to parse their \prm{text} argument, such as \cmd{mkpageprefix}. Simply nesting these commands will not work as expected. Use the \prm{postpro} argument to set up the processing chain as follows: \begin{ltxexample} \DeclareFieldFormat{postnote}{\mkcomprange[<<{>>\mkpageprefix[pagination]<<}>>]{#1}} @@ -10836,7 +10922,7 @@ The second optional argument \prm{itempostpro} is used to post-process each indi \cmditem{mknormrange}[postpro][itempostpro]{text} \cmditem*{mknormrange*}[postpro][itempostpro]{text} -This command, which is intended for use in field formatting directives, will parse its \prm{text} argument for page ranges and will normalise them. The command is similar to \cmd{mkcomprange} except that the page ranges will not be compressed. The scanner recognises \cmd{bibrangedash} and hyphens as range dashes. It will normalize the dash by replacing any number of consecutive hyphens with \cmd{bibrangedash}. Lists of ranges delimited with \cmd{bibrangessep} are also supported. The scanner will normalise any comma or semi-colons surrounded by optional space by replacing them with \cmd{bibrangessep}. If you want to hide a character from the list/range scanner for some reason, wrap the character or the entire string in curly braces. The optional \prm{postpro} argument specifies a macro to be used for post-processing the \prm{text}. See \cmd{mkcomprange} on how to use this argument. The starred version of this command differs from the regular one in the way the \prm{postpro} argument is applied to a list of values. The second optional argument \prm{itempostpro} is used to post-process each individual number item in the formatted list. It can be used to convert numbers from cardinals to ordinals. If only one optional argument is present, it is treated as \prm{postpro}. +This command, which is intended for use in field formatting directives, will parse its \prm{text} argument for page ranges and will normalise them. The command is similar to \cmd{mkcomprange} except that the page ranges will not be compressed. The scanner recognises \cmd{bibrangedash} and hyphens as range dashes. It will normalize the dash by replacing any number of consecutive hyphens with \cmd{bibrangedash}. Lists of ranges delimited with \cmd{bibrangessep} are also supported. The scanner will normalise any comma or semicolons surrounded by optional space by replacing them with \cmd{bibrangessep}. If you want to hide a character from the list/range scanner for some reason, wrap the character or the entire string in curly braces. The optional \prm{postpro} argument specifies a macro to be used for post-processing the \prm{text}. See \cmd{mkcomprange} on how to use this argument. The starred version of this command differs from the regular one in the way the \prm{postpro} argument is applied to a list of values. The second optional argument \prm{itempostpro} is used to post-process each individual number item in the formatted list. It can be used to convert numbers from cardinals to ordinals. If only one optional argument is present, it is treated as \prm{postpro}. \cmditem{mkfirstpage}[postpro][itempostpro]{text} \cmditem*{mkfirstpage*}[postpro][itempostpro]{text} @@ -11361,9 +11447,13 @@ Similar to \cmd{bibxstring} but always uses the long string, ignoring the \opt{a Similar to \cmd{bibxstring} but always uses the short string, ignoring the \opt{abbreviate} option. -\cmditem{mainlang} +\cmditem{mainlang}\DeprecatedMark + +Switches from the current language to the main document language. This command is deprecated. Use the text-macro \cmd{textmainlang} instead. With \sty{babel} this command will need to be wrapped into \emph{two} groups to have purely local effect. -Switches from the current language to the main document language. This can be used the \prm{wrapper} argument in the localisation string commands above. +\cmditem{textmainlang}{text} + +Locally switches from the current language to the main document language to typeset \prm{text}. This can be used the \prm{wrapper} argument in the localisation string commands above. \end{ltxsyntax} @@ -11944,6 +12034,7 @@ Other expressions frequently used in citations: \begin{keymarglist} \item[langamerican] The language or . +\item[langbasque] The language . \item[langbrazilian] The language or . \item[langbulgarian] The language . \item[langcatalan] The language . @@ -11980,6 +12071,7 @@ The following strings are intended for use in phrases like or . +\item[frombasque] The expression . \item[frombrazilian] The expression or . \item[frombulgarian] The expression . \item[fromcatalan] The expression . @@ -14428,6 +14520,14 @@ use$<$name$>$ &\+&\+&\_&\+&\+&\_&\_\\ This revision history is a list of changes relevant to users of this package. Changes of a more technical nature which do not affect the user interface or the behavior of the package are not included in the list. More technical details are to be found in the \file{CHANGES.md} file. The numbers on the right indicate the relevant section of this manual. \begin{changelog} +\begin{release}{3.16}{2020-12} +\item Added named refcontext support to \cmd{assignrefcontext*}\see{use:bib:context} +\item Fixed infinite loop with \bibfield{volcitepages} field format +\item Added Extended Name Format documentation\see{use:enf} +\item Added \opt{label} option to \cmd{printbibliography}\see{use:bib:bib} +\item Deprecate \cmd{mainlang} in favour of \cmd{textmainlang}\see{aut:str} +\item Added Basque localisation (Ander Zarketa-Astigarraga) +\end{release} \begin{release}{3.15a}{2020-08-23} \item Fixed bug with long arguments in \cmd{DeclareFieldFormat} and friends \end{release} diff --git a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf index 6b221f760d..141a79e6a7 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf and b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-biber.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf index 2d5254f846..b10bb33409 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf and b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys-bibtex.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex index 84f46d5a6c..445c000498 100644 --- a/macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex +++ b/macros/latex/contrib/biblatex/doc/examples/03-localization-keys.tex @@ -584,6 +584,7 @@ Other expressions frequently used in citations: \begin{keylist} \keyitem{langamerican} The language or . +\keyitem{langbasque} The language . \keyitem{langbrazilian} The language or . \keyitem{langbulgarian} The language . \keyitem{langcatalan} The language . @@ -620,6 +621,7 @@ The following strings are intended for use in phrases like or . +\keyitem{frombasque} The expression . \keyitem{frombrazilian} The expression or . \keyitem{frombulgarian} The expression . \keyitem{fromcatalan} The expression . diff --git a/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf b/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf index 127d8ca0d7..64db9af5a6 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf and b/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.tex b/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.tex deleted file mode 100644 index 2ba9fa7417..0000000000 --- a/macros/latex/contrib/biblatex/doc/examples/16-numeric-prefixed-1-bibtex.tex +++ /dev/null @@ -1,53 +0,0 @@ -% -% This file demonstrates how to configure biblatex to prefix -% numerical citations with a letter or a string. This will work with -% all numerical styles which ship with biblatex. Note that you must -% set defernumbers=true globally when using prefixes. -% -% Since the prefixes are assigned as the bibliography is generated, -% you may use any filter supported by biblatex to subdivide the -% references (by type, by category, by keyword, etc.). -% -\documentclass[a4paper,oneside]{article} -\usepackage[T1]{fontenc} -\usepackage[american]{babel} -\usepackage{csquotes} -% When using prefixed numerical labels, the labels must be assigned -% as the bibliography is generated. That's why we set -% defernumbers=true here: -\usepackage[style=numeric,defernumbers,backend=bibtex]{biblatex} -\usepackage{hyperref} -\usepackage{nameref} -\addbibresource{biblatex-examples.bib} -% A catch-all filter for all items which are not assigned to a -% dedicated sub-bibliography: -\defbibfilter{other}{ - not type=article - and - not type=book - and - not type=collection -} - -\begin{document} - -\section*{Prefixed numerical citations} - -% Some citations: -\cite{angenendt, kastenholz, augustine, companion, jaffe, ctan} - -\nocite{*} - -% Let's print the overall heading of the bibliography first: -\printbibheading - -% And now the sub-bibliographies: we use three of them (based on the -% entry type). Each sub-bibliography assigns a different prefix: -\printbibliography[heading=subbibliography,title={Articles},type=article, prefixnumbers={A}] -\printbibliography[heading=subbibliography,title={Books},type=book, prefixnumbers={B}] -\printbibliography[heading=subbibliography,title={Collections},type=collection, prefixnumbers={C}] - -% The catch-all sub-bibliography for all remaining types: -\printbibliography[heading=subbibliography,title={Other Sources},filter=other, prefixnumbers={O}] - -\end{document} diff --git a/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf b/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf index 5c29ad4479..1660f1fa12 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf and b/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.tex b/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.tex deleted file mode 100644 index c0952bab42..0000000000 --- a/macros/latex/contrib/biblatex/doc/examples/17-numeric-prefixed-2-bibtex.tex +++ /dev/null @@ -1,40 +0,0 @@ -% -% This example is almost the same as the previous one except that -% the catch-all sub-bibliography does not assign any prefix. -% -\documentclass[a4paper,oneside]{article} -\usepackage[T1]{fontenc} -\usepackage[american]{babel} -\usepackage{csquotes} -\usepackage[style=numeric,defernumbers,backend=bibtex]{biblatex} -\usepackage{hyperref} -\usepackage{nameref} -\addbibresource{biblatex-examples.bib} -\defbibfilter{other}{ - not type=article - and - not type=book - and - not type=collection -} -\begin{document} - -\section*{Prefixed numerical citations} - -% Some citations: -\cite{angenendt, kastenholz, augustine, companion, jaffe, ctan} - -\nocite{*} - -\printbibheading - -\printbibliography[heading=subbibliography,title={Articles},type=article, prefixnumbers={A}] -\printbibliography[heading=subbibliography,title={Books},type=book, prefixnumbers={A}] -\printbibliography[heading=subbibliography,title={Collections},type=collection, prefixnumbers={C}] - -% The catch-all sub-bibliography for all remaining types. We don't -% use a prefix but we still need to set resetnumbers=true to restart -% the item numbering: -\printbibliography[heading=subbibliography,title={Other Sources},filter=other,resetnumbers] - -\end{document} diff --git a/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf b/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf index 12ee886cf2..fd02d3ee77 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf and b/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.tex b/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.tex deleted file mode 100644 index 31cac5de0b..0000000000 --- a/macros/latex/contrib/biblatex/doc/examples/19-alphabetic-prefixed-bibtex.tex +++ /dev/null @@ -1,44 +0,0 @@ -% -% Prefixes also work with alphabetic the styles. -% -\documentclass[a4paper,oneside]{article} -\usepackage[T1]{fontenc} -\usepackage[american]{babel} -\usepackage{csquotes} -\usepackage[style=alphabetic,backend=bibtex]{biblatex} -\usepackage{hyperref} -\usepackage{nameref} -\addbibresource{biblatex-examples.bib} -% A catch-all filter for all items which are not assigned to a -% dedicated sub-bibliography: -\defbibfilter{other}{ - not type=article - and - not type=book - and - not type=collection -} -\begin{document} - -\section*{Prefixed alphabetic citations} - -% Some citations: -\cite{angenendt, kastenholz, augustine, companion, jaffe, ctan} - -\nocite{*} - -% Let's print the overall heading of the bibliography first: -\printbibheading - -% And now the sub-bibliographies: we use three of them (based on the -% entry type). Each sub-bibliography assigns a different prefix. The -% option is called 'prefixnumbers' because it was originally intended -% for numeric citations only. It also works with alphabetic labels: -\printbibliography[heading=subbibliography,title={Articles},type=article,prefixnumbers={A-}] -\printbibliography[heading=subbibliography,title={Books},type=book,prefixnumbers={B-}] -\printbibliography[heading=subbibliography,title={Collections},type=collection,prefixnumbers={C-}] - -% The catch-all sub-bibliography for all remaining types: -\printbibliography[heading=subbibliography,title={Other Sources},filter=other,prefixnumbers={O-}] - -\end{document} diff --git a/macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf b/macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf index eb9d127563..d737632db1 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf and b/macros/latex/contrib/biblatex/doc/examples/82-style-debug-biber.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf b/macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf index 3b422be09e..e9368e5e45 100644 Binary files a/macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf and b/macros/latex/contrib/biblatex/doc/examples/93-nameparts-biber.pdf differ diff --git a/macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex b/macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex index 71b6a5b219..44115b6acd 100644 --- a/macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex +++ b/macros/latex/contrib/biblatex/doc/examples/93-nameparts.tex @@ -1,15 +1,10 @@ \documentclass[a4paper]{article} \usepackage{fontspec} -\setmainfont{Linux Libertine O} -\setsansfont{Linux Biolinum O} +\usepackage{libertine} \usepackage[fallback]{xeCJK} -%\setCJKmainfont{Malgun Gothic} -\setCJKmainfont{PingFang TC}% OSX - \usepackage[british]{babel} \usepackage{csquotes} -\usepackage{filecontents} -\begin{filecontents}{\jobname.bib} +\begin{filecontents}[force]{\jobname.bib} @book{tolstoy, author = {given=Лев, patronymic=Николаевич, family=Толстой, nametemplates=russian}, title = {Война и мир}, @@ -84,14 +79,6 @@ publisher = {Shangwu Yinshuguan}, date = {2016}, } -@book{zhangh, - title = {Sŏmyŏng}, - titleaddon = {書名}, - author = {family=Zhang, cjk=장학성, given=Haksŏng, nametemplates=cjk}, - location = {Shanghai}, - publisher = {Shangwu Yinshuguan}, - date = {2016}, -} @book{bronte:c, author = {Charlotte Brontë}, @@ -433,7 +420,7 @@ \textcite{bronte:c,bronte:e,austen:jane,austen:john} -\textcite{zhangx1,zhangx2,zhangh} +\textcite{zhangx1,zhangx2} \printbibliography \end{document} diff --git a/macros/latex/contrib/biblatex/doc/examples/96-dates.tex b/macros/latex/contrib/biblatex/doc/examples/96-dates.tex index e4e1863934..d1e88e2f53 100644 --- a/macros/latex/contrib/biblatex/doc/examples/96-dates.tex +++ b/macros/latex/contrib/biblatex/doc/examples/96-dates.tex @@ -6,8 +6,7 @@ \usepackage{fontspec} \usepackage[american]{babel} \usepackage{csquotes} -\usepackage{filecontents} -\begin{filecontents}{\jobname.bib} +\begin{filecontents}[force]{\jobname.bib} @misc{date1, note = {Years with implicit era}, author = {Author1}, diff --git a/macros/latex/contrib/biblatex/doc/examples/97-annotations.tex b/macros/latex/contrib/biblatex/doc/examples/97-annotations.tex index 03be50f142..a756b7ce00 100644 --- a/macros/latex/contrib/biblatex/doc/examples/97-annotations.tex +++ b/macros/latex/contrib/biblatex/doc/examples/97-annotations.tex @@ -5,8 +5,7 @@ \usepackage{fontspec} \usepackage[american]{babel} \usepackage{csquotes} -\usepackage{filecontents} -\begin{filecontents}{\jobname.bib} +\begin{filecontents}[force]{\jobname.bib} @MISC{ann1, AUTHOR = {Last1, First1 and Last2, First2 and Last3, First3}, AUTHOR+an = {1:family=student;2=corresponding}, diff --git a/macros/latex/contrib/biblatex/latex/bbx/draft.bbx b/macros/latex/contrib/biblatex/latex/bbx/draft.bbx index 1c57325157..0896a6d963 100644 --- a/macros/latex/contrib/biblatex/latex/bbx/draft.bbx +++ b/macros/latex/contrib/biblatex/latex/bbx/draft.bbx @@ -8,6 +8,10 @@ \DeclareNameAlias{editor}{default} \DeclareNameAlias{translator}{default} +\DeclareNameWrapperAlias{author}{default} +\DeclareNameWrapperAlias{editor}{default} +\DeclareNameWrapperAlias{translator}{default} + \DeclareFieldFormat{shorthandwidth}{#1} \defbibenvironment{bibliography} diff --git a/macros/latex/contrib/biblatex/latex/bbx/numeric.bbx b/macros/latex/contrib/biblatex/latex/bbx/numeric.bbx index 4bf46c3ff8..909b806fd1 100644 --- a/macros/latex/contrib/biblatex/latex/bbx/numeric.bbx +++ b/macros/latex/contrib/biblatex/latex/bbx/numeric.bbx @@ -13,6 +13,10 @@ \DeclareNameAlias{editor}{default} \DeclareNameAlias{translator}{default} +\DeclareNameWrapperAlias{author}{default} +\DeclareNameWrapperAlias{editor}{default} +\DeclareNameWrapperAlias{translator}{default} + \DeclareFieldFormat{bibentrysetcount}{\mkbibparens{\mknumalph{#1}}} \DeclareFieldFormat{labelnumberwidth}{\mkbibbrackets{#1}} \DeclareFieldFormat{shorthandwidth}{\mkbibbrackets{#1}} diff --git a/macros/latex/contrib/biblatex/latex/bbx/reading.bbx b/macros/latex/contrib/biblatex/latex/bbx/reading.bbx index 547510c37d..3eb35c3909 100644 --- a/macros/latex/contrib/biblatex/latex/bbx/reading.bbx +++ b/macros/latex/contrib/biblatex/latex/bbx/reading.bbx @@ -7,6 +7,10 @@ \DeclareNameAlias{editor}{default} \DeclareNameAlias{translator}{default} +\DeclareNameWrapperAlias{author}{default} +\DeclareNameWrapperAlias{editor}{default} +\DeclareNameWrapperAlias{translator}{default} + \DeclareFieldFormat{entrykey}{\mbox{\bfseries#1}} \DeclareFieldFormat{annotation}{\bibstring{annotation}\addcolon\space #1} \DeclareFieldFormat{abstract}{\bibstring{abstract}\addcolon\space #1} diff --git a/macros/latex/contrib/biblatex/latex/bbx/standard.bbx b/macros/latex/contrib/biblatex/latex/bbx/standard.bbx index 810c8584c9..f53eb722d5 100644 --- a/macros/latex/contrib/biblatex/latex/bbx/standard.bbx +++ b/macros/latex/contrib/biblatex/latex/bbx/standard.bbx @@ -983,14 +983,14 @@ test {\ifbibxstring{\thefield{relatedtype}s}} } {\printtext[\bbx@tempb]{% - \bibstring[\mkrelatedstring]{\thefield{relatedtype}s}}} + \bibstring[\mkrelatedstringtext]{\thefield{relatedtype}s}}} {\iffieldbibstring{relatedtype} {\printtext[\bbx@tempb]{% - \bibstring[\mkrelatedstring]{\thefield{relatedtype}}}} + \bibstring[\mkrelatedstringtext]{\thefield{relatedtype}}}} {}}} {\iffieldbibstring{relatedstring} {\printtext[\bbx@tempb]{% - \bibstring[\mkrelatedstring]{\thefield{relatedstring}}}} + \bibstring[\mkrelatedstringtext]{\thefield{relatedstring}}}} {\printfield[\bbx@tempb]{relatedstring}}}% \docsvfield{related}% \usebibmacro{endrelatedloop}}}% diff --git a/macros/latex/contrib/biblatex/latex/biblatex.def b/macros/latex/contrib/biblatex/latex/biblatex.def index 10f4144dab..c4ac8d0169 100644 --- a/macros/latex/contrib/biblatex/latex/biblatex.def +++ b/macros/latex/contrib/biblatex/latex/biblatex.def @@ -194,7 +194,7 @@ % Examples of use, uncommenting these would break backwards compatibility %\newcommand*{\begrelateddelimorigpubin}{\addspace} %\newcommand*{\begrelateddelimorigpubas}{\addspace} -\newcommand{\mkrelatedstring}{\mainlang} +\newcommand{\mkrelatedstringtext}{\textmainlang} % Used for indexing @@ -476,7 +476,7 @@ \DeclareFieldFormat{prenote}{#1\isdot} \DeclareFieldFormat{postnote}{\mkpageprefix[pagination][\mknormrange]{#1}} \DeclareFieldFormat{volcitevolume}{\bibstring{volume}\ppspace#1} -\DeclareFieldAlias{volcitepages}{postnote} +\DeclareFieldFormat{volcitepages}{\mkpageprefix[pagination][\mknormrange]{#1}} \DeclareFieldFormat{volcitenote}{\mkvolcitenote#1} \newrobustcmd*{\mkvolcitenote}[2]{% \printtext[volcitevolume]{#1}% @@ -624,6 +624,7 @@ % The default used by \citelist \DeclareListAlias{citelist}{default} +\DeclareListWrapperAlias{citelist}{default} % Used in the bibliography @@ -724,6 +725,11 @@ \DeclareListAlias{institution}{default} \DeclareListAlias{organization}{default} +\DeclareListWrapperAlias{origlocation}{location} +\DeclareListWrapperAlias{origpublisher}{publisher} +\DeclareListWrapperAlias{institution}{default} +\DeclareListWrapperAlias{organization}{default} + % Auxiliary macros for list formatting directives % ------------------------------------------------------------------ @@ -943,6 +949,7 @@ % Default used by \citename \DeclareNameAlias{citename}{default} +\DeclareNameWrapperAlias{citename}{default} % Used in some citations \DeclareNameFormat{labelname}{% @@ -998,6 +1005,28 @@ \DeclareNameAlias{withforeword}{default} \DeclareNameAlias{withafterword}{default} +\DeclareNameWrapperAlias{author}{default} +\DeclareNameWrapperAlias{bookauthor}{author} +\DeclareNameWrapperAlias{editor}{default} +\DeclareNameWrapperAlias{editora}{editor} +\DeclareNameWrapperAlias{editorb}{editor} +\DeclareNameWrapperAlias{editorc}{editor} +\DeclareNameWrapperAlias{translator}{default} + +\DeclareNameWrapperAlias{byauthor}{default} +\DeclareNameWrapperAlias{bybookauthor}{byauthor} +\DeclareNameWrapperAlias{byeditor}{default} +\DeclareNameWrapperAlias{byeditora}{byeditor} +\DeclareNameWrapperAlias{byeditorb}{byeditor} +\DeclareNameWrapperAlias{byeditorc}{byeditor} +\DeclareNameWrapperAlias{bytranslator}{default} + +\DeclareNameWrapperAlias{withcommentator}{default} +\DeclareNameWrapperAlias{withannotator}{default} +\DeclareNameWrapperAlias{withintroduction}{default} +\DeclareNameWrapperAlias{withforeword}{default} +\DeclareNameWrapperAlias{withafterword}{default} + \DeclareFieldFormat{authortype}{#1} \DeclareFieldFormat{editortype}{#1} \DeclareFieldFormat{translatortype}{#1} @@ -2963,13 +2992,10 @@ \entrydata{#1}{% \renewbibmacro*{name:hook}[1]{% \ifnumequal{\value{listcount}}{1} - {\begingroup - \mkrelatedstring% - \lbx@initnamehook{#1}% - \endgroup} + {\mkrelatedstringtext{\lbx@initnamehook{##1}}} {}}% \printnames[bytranslator]{translator}% - \setunit*{\addspace\bibstring[\mkrelatedstring]{astitle}\space}% + \setunit*{\addspace\bibstring[\mkrelatedstringtext]{astitle}\space}% \usebibmacro{title}% \setunit{\addspace}% \printtext[parens]{% @@ -3017,7 +3043,7 @@ test {\iflistundef{publisher}} } {} - {\setunit{\addspace\bibstring[\mkrelatedstring]{bypublisher}\space}% + {\setunit{\addspace\bibstring[\mkrelatedstringtext]{bypublisher}\space}% \printlist{publisher}% \setunit{\addcomma\space}% \iflistsequal{location}{savedlocation} @@ -3033,7 +3059,7 @@ test {\iflistundef{publisher}} } {} - {\setunit{\addspace\bibstring[\mkrelatedstring]{bypublisher}\space}% + {\setunit{\addspace\bibstring[\mkrelatedstringtext]{bypublisher}\space}% \printlist{publisher}% \setunit{\addcomma\space}% \iflistsequal{location}{savedlocation} @@ -3041,10 +3067,7 @@ {\printlist{location}}}}} \DeclareFieldFormat{title:hook}{% - \begingroup - \mkrelatedstring% - \lbx@inittitlehook{#1}% - \endgroup + \mkrelatedstringtext{\lbx@inittitlehook{#1}}% \mkbibemph{#1}} \newbibmacro*{related:reprintfrom}[1]{% diff --git a/macros/latex/contrib/biblatex/latex/biblatex.sty b/macros/latex/contrib/biblatex/latex/biblatex.sty index 22da31e261..e24c735007 100644 --- a/macros/latex/contrib/biblatex/latex/biblatex.sty +++ b/macros/latex/contrib/biblatex/latex/biblatex.sty @@ -12,8 +12,8 @@ % particular purpose. % Set up the version strings here -\def\abx@date{2020/08/23} -\def\abx@version{3.15a} +\def\abx@date{2020/12/31} +\def\abx@version{3.16} \def\abx@bbxid{\abx@date\space v\abx@version\space biblatex bibliography style (PK/MW)} \def\abx@cbxid{\abx@date\space v\abx@version\space biblatex citation style (PK/MW)} \def\abx@lbxid{\abx@date\space v\abx@version\space biblatex localization (PK/MW)} @@ -52,6 +52,20 @@ This is a fatal error. I'm aborting now}% \endinput} +% The new hook management system in LaTeX 2020-10-01 and above +% no longer guarantees that \AtBeginDocument/AfterPreamble +% are executed in order of use. +% Instead each use of those commands gets a 'label' +% and code for the same label is chunked together. +% We give our \AfterPreamble invocations a new label and set up a rule to +% have it executed after all normal biblatex \AtBeginDocument stuff. +% Note that begindocument is a one-time hook, so we are guaranteed +% immediate execution when inside \begin{document}...\end{document}. +\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} +\IfFormatAtLeastTF{2020/10/01} + {\def\blx@AfterPreamble{\AddToHook{begindocument}[biblatex/afterpreamble]}% + \DeclareHookRule{begindocument}{biblatex/afterpreamble}{after}{biblatex}} + {\def\blx@AfterPreamble{\AfterPreamble}} % generalised keyval interface % define a new key (possibly with a default value) @@ -509,8 +523,10 @@ {\let\xpg@bloaded\xpg@loaded}} {}% \global\let\blx@maplang\blx@maplang@polyglossia - \def\do#1{\blx@langsetup{#1}}% + \def\do#1{\blx@langsetup@from@pkglist{#1}}% \expandafter\docsvlist\expandafter{\xpg@bloaded}% + \def\do#1{\blx@langsetup@from@auxlist{#1}}% + \dolistloop\blx@lbx@auxloadlist \ifboolexpr{ not togl {blx@autolangbib} and @@ -521,8 +537,10 @@ {\global\let\blx@maplang\blx@maplang@babel \@ifpackageloaded{babel} {% This is required for languages which are never explicitly selected - \def\do#1{\blx@langsetup{#1}}% + \def\do#1{\blx@langsetup@from@pkglist{#1}}% \expandafter\docsvlist\expandafter{\bbl@loaded}% + \def\do#1{\blx@langsetup@from@auxlist{#1}}% + \dolistloop\blx@lbx@auxloadlist \ifboolexpr{ not togl {blx@autolangbib} and @@ -545,7 +563,10 @@ % babel/polyglossia has loaded the (main document) language already, % so we need to explicitly enable our captions (abx@strings@) % and extras (abx@extras@) now - \toggletrue{blx@lang@captions@\blx@languagename}% + \ifdefstring{\blx@langhook}{captions} + {\blx@etb@inittoggle{blx@lang@captions@\blx@languagename}% + \toggletrue{blx@lang@captions@\blx@languagename}} + {}% \csuse{abx@extras@\blx@languagename}% \csuse{abx@strings@\blx@languagename}% % avoid accidental re-initialization @@ -637,35 +658,44 @@ in recent versions of pdfTeX, LuaTeX and XeTeX}} {\let\blx@mdfivesum\pdf@mdfivesum} +\newtoggle{blx@bbl@rerun@requested} \ifundef\pdf@filemdfivesum {\blx@warning@noline{Command '\string\pdf@filemdfivesum' undefined.\MessageBreak Biber rerun detection may not work as expected.\MessageBreak The command is available (via 'pdftexcmds')\MessageBreak in recent versions of pdfTeX, LuaTeX and XeTeX}% - \let\blx@generate@bbl@mdfivesum@found\relax + \let\blx@generate@bbl@mdfivesum@found\@gobble \let\blx@generate@bbl@mdfivesum@notfound\relax - \let\blx@aux@read@bbl@mdfivesum\@gobble + \let\abx@aux@read@bblrerun\relax + \let\abx@aux@read@bbl@mdfivesum\@gobble \let\blx@aux@write@bbl@mdfivesum\relax \let\blx@check@bbl@rerun@mdfivesum\relax} {\let\blx@filemdfivesum\pdf@filemdfivesum - \def\blx@generate@bbl@mdfivesum@found{% - \xdef\blx@bbl@mdfivesum@new{\blx@filemdfivesum{\jobname.bbl}}} + \def\blx@generate@bbl@mdfivesum@found#1{% + \xdef\blx@bbl@mdfivesum@new{\blx@filemdfivesum{#1}}} + % 'nobblfile' can never be equal to any md5 hash \def\blx@generate@bbl@mdfivesum@notfound{% \gdef\blx@bbl@mdfivesum@new{nobblfile}} - \def\blx@aux@read@bbl@mdfivesum{% + \def\abx@aux@read@bblrerun{\global\toggletrue{blx@bbl@rerun@requested}} + + \def\abx@aux@read@bbl@mdfivesum{% \gdef\blx@bbl@mdfivesum@old} % If we need Biber to rerun, save the hash of the current .bbl. % That way we can detect if the Biber rerun really happened when % we run LaTeX the next time. \def\blx@aux@write@bbl@mdfivesum{% + \blx@auxwrite\@mainaux{}{% + \string\abx@aux@read@bbl@mdfivesum{% + \ifundef\blx@bbl@mdfivesum@old + {nohash} + {\blx@bbl@mdfivesum@new}}}% \iftoggle{blx@runbiber} - {\blx@auxwrite\@mainaux{}{% - \string\blx@aux@read@bbl@mdfivesum{\blx@bbl@mdfivesum@new}}} + {\blx@auxwrite\@mainaux{}{\string\abx@aux@read@bblrerun}} {}} % There was a Biber rerun request last time (\blx@bbl@mdfivesum@old), @@ -673,9 +703,11 @@ % that means *no* Biber rerun happened. % So we need to re-request a rerun. \def\blx@check@bbl@rerun@mdfivesum{% - \ifdefstrequal\blx@bbl@mdfivesum@old\blx@bbl@mdfivesum@new - {\blx@logreq@active{}} - {}}} + \iftoggle{blx@bbl@rerun@requested} + {\ifdefstrequal\blx@bbl@mdfivesum@old\blx@bbl@mdfivesum@new} + {\@secondoftwo} + {\blx@logreq@active{}} + {}}} % xstring replacements @@ -923,6 +955,9 @@ \cslet{blx@defaultrefcontexts@0}\@empty \listadd\blx@allrefsections{0} +% Used to track defernumbers from .aux +\global\let\blx@localnumbers\@empty + % Used to track sorting name key specifications \global\let\blx@sortingnamekeytemplates\@empty @@ -2164,15 +2199,15 @@ \providerobustcmd*{\nohyphenation}{% \language\blx@langwohyphens} -% work around odd XeTeX/babel-french behaviour +% First part of workaround for odd XeTeX/babel-french behaviour % https://github.com/plk/biblatex/issues/979 % fix by Ulrike Fischer -% https://tex.stackexchange.com/a/544914/ +% https://tex.stackexchange.com/a/544914/. +% The second bit lives in blx-unicode.def. \ifundef\XeTeXrevision {\providerobustcmd*{\textnohyphenation}[1]{% \bgroup\nohyphenation#1\egroup}} - {\providerobustcmd*{\textnohyphenation}[1]{% - \bgroup\nohyphenation#1\egroup^^^^200b}} + {} \blx@regimcs{% \setpunctfont \resetpunctfont \ifcapital \autocap \ifpunctmark @@ -5203,6 +5238,7 @@ \do{november}% \do{december}% \do{langamerican}% + \do{langbasque}% \do{langbrazilian}% \do{langbulgarian}% \do{langcatalan}% @@ -5235,6 +5271,7 @@ \do{langturkish}% \do{langukrainian}% \do{fromamerican}% + \do{frombasque}% \do{frombrazilian}% \do{frombulgarian}% \do{fromcatalan}% @@ -5499,7 +5536,9 @@ \IfFileExists{#1} {\blx@info@noline{... file '#1' found}% \csuse{blx@lbxfilehook@simple@preload@#1}% - #3\@@input\@filef@und#4% + #3% + \@@input\@filef@und + #4% \csuse{blx@lbxfilehook@simple@postload@#1}% #5% \ifcsundef{blx@file@lbx@simple@#1} @@ -5518,7 +5557,9 @@ \IfFileExists{#1} {\blx@info@noline{... file '#1' found}% \csuse{blx@lbxfilehook@once@preload@#1}% - #3\@@input\@filef@und#4% + #3% + \@@input\@filef@und + #4% \csuse{blx@lbxfilehook@once@postload@#1}% #5% \ifcsundef{blx@file@lbx@simple@#1} @@ -5588,13 +5629,49 @@ \endgroup} % {} -\def\blx@langsetup#1{% +\protected\def\blx@langsetup#1{% \blx@lbxinput{#1} {\edef\blx@languagename{#1}} {\blx@warning {Language '#1' not supported.\MessageBreak Using dummy definitions}}} +\protected\def\blx@langsetup@from@pkglist#1{% + \global\cslet{blx@lbx@loaded@from@pkglist@#1}\@empty + \blx@langsetup{#1}} + +\protected\def\blx@langsetup@from@auxlist#1{% + \global\cslet{blx@lbx@loaded@from@auxlist@#1}\@empty + \blx@langsetup{#1}} + +\newcommand*{\blx@lbx@loadlist}{} + +\protected\def\blx@langsetup@indoc#1{% + \ifcsundef{blx@lbx@loaded@from@pkglist@#1} + {\xifinlist{#1}\blx@lbx@loadlist + {} + {\listxadd\blx@lbx@loadlist{#1}}% + \ifcsundef{blx@lbx@loaded@from@auxlist@#1} + {\ifcsundef{blx@lbx@loaded@nolistload@#1} + {\blx@warning@noline{% + No localisation for language '#1' loaded.\MessageBreak + Please rerun LaTeX to ensure languages can\MessageBreak + be requested properly}% + \global\cslet{blx@lbx@loaded@nolistload@#1}\@empty} + {}} + {\edef\blx@languagename{#1}}} + {\edef\blx@languagename{#1}}% +} + +\newcommand*{\blx@lbx@auxloadlist}{} + +\def\abx@aux@lbx@loadrequest{% + \listgadd\blx@lbx@auxloadlist} + +\protected\def\blx@lbx@writeloaderequest#1{% + \blx@auxwrite\@mainaux{}{% + \string\abx@aux@lbx@loadrequest{#1}}} + % auxiliary macros % {} @@ -6377,6 +6454,7 @@ \let\blx@hook@endlang\@empty \let\blx@hook@initlang\@empty \let\blx@imc@mainlang\@empty +\let\blx@imc@textmainlang\@firstofone \def\blx@hyphenreset{% \blx@ifhyphenationundef{\blx@languagename} {} @@ -6403,7 +6481,7 @@ % afterreset was added in 3.9i (~2014-03-16) % way before 3.9r (2016-04-23), which we require \AddBabelHook{biblatex@langsetup}{afterreset}{% - \expandafter\blx@langsetup\expandafter{\languagename}}% + \expandafter\blx@langsetup@indoc\expandafter{\languagename}}% \ifdef\blx@thelangenv {\def\blx@beglang{% \blx@clearlang @@ -6437,8 +6515,20 @@ {}}} {}% \def\blx@imc@mainlang{% + \ifundef\blx@warn@mainlang + {\blx@warning@noline{% + '\string\mainlang' is deprecated in favour of\MessageBreak + '\string\textmainlang'.% + \MessageBreak + Please consider using the new command,\MessageBreak + but note that the syntax is different.\MessageBreak + Using the old, problematic definition}% + \global\let\blx@warn@mainlang\@empty} + {}% \expandafter\selectlanguage\expandafter{\blx@main@language}}% - \expandafter\blx@langsetup\expandafter{\blx@main@language}% + \def\blx@imc@textmainlang##1{% + {{\expandafter\selectlanguage\expandafter{\blx@main@language}##1}}}% + \expandafter\blx@langsetup@from@pkglist\expandafter{\blx@main@language}% } \def\blx@beglang@spacefactors{\frenchspacing} @@ -6453,12 +6543,12 @@ {\let\blx@main@language\mainbabelname}% \ifundef\polyglossia@language@switched {\apptocmd\select@language - {\expandafter\blx@langsetup\expandafter{\babelname}} + {\expandafter\blx@langsetup@indoc\expandafter{\babelname}} {} {\blx@err@patch{'polyglossia' package}% \blx@mknoautolang}} {\appto\polyglossia@language@switched{% - \expandafter\blx@langsetup\expandafter{\babelname}}}% + \expandafter\blx@langsetup@indoc\expandafter{\babelname}}}% \ifdef\blx@thelangenv {\def\blx@beglang{% \blx@clearlang @@ -6500,15 +6590,27 @@ \blx@beglang@spacefactors}} {}}} {}% - \def\blx@imc@mainlang{\select@language{\blx@main@language}}% - \expandafter\blx@langsetup\expandafter{\blx@main@language}} + \def\blx@imc@mainlang{% + \ifundef\blx@warn@mainlang + {\blx@warning@noline{% + '\string\mainlang' is deprecated in favour of\MessageBreak + '\string\textmainlang'.% + \MessageBreak + Please consider using the new command,\MessageBreak + but note that the syntax is different.\MessageBreak + Using the old, problematic definition}% + \global\let\blx@warn@mainlang\@empty} + {}% + \select@language{\blx@main@language}}% + \def\blx@imc@textmainlang##1{{{\select@language{\blx@main@language}##1}}}% + \expandafter\blx@langsetup@from@pkglist\expandafter{\blx@main@language}} \def\blx@mknoautolang{% \blx@lbxinput{\blx@languagename} {} {\blx@err@nolang{\blx@languagename}}} -\blx@regimcs{\mainlang} +\blx@regimcs{\mainlang \textmainlang} \newrobustcmd*{\DeclareRedundantLanguages}[2]{% \begingroup @@ -8302,14 +8404,14 @@ \abx@flfw@getfieldformat{abx@flfw@labelnumberwidth}{labelnumberwidth}{}% \abx@flfw@getfieldformat{abx@flfw@labelprefix}{labelprefix}{}% \abx@flfw@getfieldformat{abx@flfw@labelnumber}{labelnumber}{}% - \iftoggle{blx@defernumbers} - {\ifundef\abx@field@localnumber - {\numdef\abx@field@localnumber{0}}% - {}} - {\ifundef\abx@field@localnumber - {\edef\abx@field@localnumber{% - \csuse{blx@labelnumber@\the\c@refsection}}} - {}}% + \iftoggle{blx@defernumbers} + {\ifundef\abx@field@localnumber + {\numdef\abx@field@localnumber{0}}% + {}} + {\ifundef\abx@field@localnumber + {\edef\abx@field@localnumber{% + \csuse{blx@labelnumber@\the\c@refsection}}} + {}}% \blx@setlabwidth{\csname #1labelnumberwidth\endcsname}{% \csuse{abx@flfw@labelnumberwidth}{% \ifdef\abx@field@labelprefix @@ -8549,13 +8651,18 @@ % any citations or add/remove any sorting templates, we need to re-run % biber. Also, if we have to re-run biber, we need to defer writing % the defernumbers .aux information because it will not yet be correct. - + \begingroup + % Test to see if there are any .aux entries with defernums (localnum) + % information which are no longer in the .bbl. This is to catch + % when .bib entries are removed when using \nocite{*}. In this case, + % We need another run to remove the .aux localnumber info + \def\do#1{\xifinlist{#1}\blx@entries{}{\blx@rerun@latex}}% + \dolistloop\blx@localnumbers % Test to see if we *removed* any citations since last run % (adding citations is dealt with naturally in \blx@citation@entry) % If so, give a rerun biber message. This also sets the % rerun biber toggle so defernums doesn't consume the localnumbers % in the .aux but instead, re-writes them, which is what we need. - \begingroup \def\do#1{\ifinlist{#1}\blx@cites{}{\blx@logreq@active{}}\relax}% \dolistloop\blx@lastcites % Special case - if we are using sortingtemplate with \citeorder anywhere, @@ -8603,9 +8710,16 @@ {\def\do#1{\blx@auxwrite\@mainaux{}{#1}} \dolistloop\blx@localnumaux}} {}% - % Wite md5 hash of .bbl to .aux if we need a Biber rerun. + % Write out missing languages we still need to load + \forlistloop{\blx@lbx@writeloaderequest}{\blx@lbx@loadlist}% + % Issue rerun warning if we need to load a language babel/polyglossia + % hasn't told us about and that we are not loading it already from previous + % runs. + \def\do#1{\xifinlist{#1}{\blx@lbx@auxloadlist}{}{\blx@rerun@latex\listbreak}}% + \dolistloop\blx@lbx@loadlist + % Write md5 hash of .bbl to .aux if we need a Biber rerun. % This needs to happen here and not in \blx@check@rerun together with - % the other rerun stuff, because \AfterEndBibliography would be too + % the other rerun stuff, because \AfterEndDocument would be too % late for .aux file writing. \blx@aux@write@bbl@mdfivesum \endgroup} @@ -8614,6 +8728,8 @@ \protected\def\blx@aux@number#1#2#3#4#5{% \blx@bbl@addentryfield{\detokenize{#2}}{#3}{localnumber}{#4}{#5}% \blx@bbl@addentryfield{\detokenize{#2}}{#3}{labelnumber}{#4}{#5}% + \csgdef{blx@localnumber@#3@\detokenize{#2}}{#5}% + \xifinlist{\detokenize{#2}}\blx@localnumbers{}{\listxadd\blx@localnumbers{\detokenize{#2}}}% \global\toggletrue{blx@localnumber}% \ifblank{#5} {} @@ -8632,9 +8748,14 @@ % Also, don't want to regenerate localnumber for any key in a % refsection which we've already seen because this has the nasty % side-effect of incrementing the localnum counter - {\ifboolexpr { not togl {blx@localnumber} - and - not test {\ifcsdef{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey}} } + % Also, have to create localnumber again if \nocite{*} as items + % could have been added to the .bib file without changing the cite + % information in the .tex + {\ifboolexpr { (not togl {blx@localnumber} + or + test {\ifinlist{*}\blx@nocites}) + and + not test {\ifcsdef{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey}} } {\iftoggle{blx@omitnumbers} {\let\abx@field@localnumber\@empty} {\csnumgdef{blx@labelnumber@\the\c@refsection}{% @@ -8642,7 +8763,17 @@ \edef\abx@field@localnumber{% \csuse{blx@labelnumber@\the\c@refsection}}% \blx@bbl@addentryfield{\abx@field@entrykey}{\the\c@refsection}% - {localnumber}{\blx@refcontext@context}{\abx@field@localnumber}}} + {localnumber}{\blx@refcontext@context}{\abx@field@localnumber}}} + {}% + % Issue re-run message if there was no localnumber in the .aux and + % \nocite{*} was used because this means that an entry was added to the .bib + % and was not yet recorded in the .aux. We will have generated a localnumber + % for such a case above and now we need to re-run to make sure it's in the .aux + % for the next run + \ifboolexpr { test {\ifinlist{*}\blx@nocites} + and + not test {\ifcsdef{blx@localnumber@\the\c@refsection @\abx@field@entrykey}} } + {\blx@rerun@latex} {}% % If localnumbers were already in the .aux, add them % again from the .aux. This prevents some cycling @@ -8653,8 +8784,8 @@ \ifcsundef{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey} {\ifundef\abx@field@localnumber {} - {\listxadd\blx@localnumaux{% - \string\abx@aux@number% + {\listxadd\blx@localnumaux{% + \string\abx@aux@number% {\the\c@instcount}% {\abx@field@entrykey}% {\the\c@refsection}% @@ -8707,10 +8838,9 @@ {\InputIfFileExists{\jobname.bbl} {\blx@info@noline{... file '\jobname.bbl' found}% \global\toggletrue{blx@bbldone}% - \blx@generate@bbl@mdfivesum@found} + \blx@generate@bbl@mdfivesum@found{\jobname.bbl}} {\blx@info@noline{... file '\jobname.bbl' not found}% \typeout{No file \jobname.bbl.}% - % 'nobblfile' can never be equal to any mdfivehash \blx@generate@bbl@mdfivesum@notfound}} {\blx@generate@bbl@mdfivesum@notfound}% \blx@bblend @@ -8848,6 +8978,7 @@ \blx@kv@defkey{blx@bib1}{heading}{} \blx@kv@defkey{blx@bib1}{env}{} \blx@kv@defkey{blx@bib1}{title}{} +\blx@kv@defkey{blx@bib1}{label}{} \blx@kv@defkey{blx@bib1}{prenote}{} \blx@kv@defkey{blx@bib1}{postnote}{} \blx@kv@defkey{blx@bib1}{omitnumbers}[]{} @@ -8874,6 +9005,7 @@ \blx@kv@defkey{blx@biblist1}{heading}{} \blx@kv@defkey{blx@biblist1}{env}{} \blx@kv@defkey{blx@biblist1}{title}{} +\blx@kv@defkey{blx@biblist1}{label}{} \blx@kv@defkey{blx@biblist1}{prenote}{} \blx@kv@defkey{blx@biblist1}{postnote}{} @@ -9079,6 +9211,10 @@ \blx@kv@defkey{blx@bib2}{title}{\def\blx@thetitle{#1}} \blx@kv@defkey{blx@biblist2}{title}{\def\blx@thetitle{#1}} +\blx@kv@defkey{blx@bhd}{label}{\def\blx@thelabel{#1}} +\blx@kv@defkey{blx@bib2}{label}{\def\blx@thelabel{#1}} +\blx@kv@defkey{blx@biblist2}{label}{\def\blx@thelabel{#1}} + \cslet{blx@note@}\@empty \def\blx@key@bibnote#1#2{% \ifcsundef{blx@note@#2} @@ -9168,10 +9304,12 @@ \def\blx@printbibheading[#1]{% \let\blx@theheading\blx@default@theheading \let\blx@thetitle\blx@default@thetitle + \undef\blx@thelabel \blx@safe@actives \blx@kv@setkeys{blx@bhd}{#1}% \blx@rest@actives \blx@bibheading\blx@theheading\blx@thetitle + \blx@biblabel\blx@thelabel \endgroup} % We use this to determine whether an explicit value for resetnumbers is passed to @@ -9196,6 +9334,7 @@ \let\blx@theprenote\blx@default@theprenote \let\blx@thepostnote\blx@default@thepostnote \let\blx@thetitle\blx@default@thetitle + \undef\blx@thelabel % defaults \let\blx@tempa\@empty% before there is a .bbl, this must not be undef \edef\blx@tempe{\the\c@refsection}% default refsection is current @@ -9250,6 +9389,7 @@ \let\blx@theprenote\blx@default@theprenote \let\blx@thepostnote\blx@default@thepostnote \let\blx@thetitle\blx@default@thetitle + \undef\blx@thelabel \c@refsection\z@ \blx@safe@actives \blx@kv@setkeys{blx@bbs}{#1}% @@ -9289,6 +9429,7 @@ \let\blx@theprenote\blx@default@theprenote \let\blx@thepostnote\blx@default@thepostnote \let\blx@thetitle\blx@default@thetitle + \undef\blx@thelabel \c@refsegment\@ne \blx@safe@actives \blx@kv@setkeys{blx@bbg}{#1}% @@ -9333,6 +9474,7 @@ \let\blx@theprenote\blx@default@theprenote \let\blx@thepostnote\blx@default@thepostnote \let\blx@thetitle\blx@default@thetitle + \undef\blx@thelabel \c@refsection\z@ \blx@safe@actives \blx@kv@setkeys{blx@bbc}{#1}% @@ -9361,6 +9503,7 @@ % {,...} \def\blx@bibliography{% \blx@bibheading\blx@theheading\blx@thetitle + \blx@biblabel\blx@thelabel \blx@bibnote\blx@theprenote \begingroup \blx@bibinit @@ -9403,6 +9546,11 @@ \let\newrefsection\blx@newrefsection \let\newrefsegment\blx@newrefsegment} +\def\blx@biblabel#1{% + \ifdefvoid#1 + {} + {\expandafter\label\expandafter{#1}}} + \def\blx@bibnote#1{% \ifdefempty#1 {} @@ -9631,6 +9779,7 @@ \let\blx@theprenote\@empty \let\blx@thepostnote\@empty \let\blx@thetitle\@empty + \undef\blx@thelabel % defaults \let\blx@tempa\@empty% before there is a .bbl, this must not be undef % default sorting template and template name for list is same name as list @@ -9713,6 +9862,7 @@ \@restonecolfalse \fi \blx@bibheading\blx@theheading\blx@thetitle + \blx@biblabel\blx@thelabel \blx@bibnote\blx@theprenote \begingroup \blx@bibinit @@ -9900,6 +10050,7 @@ \let\blx@tempc\@empty% \def\blx@tempd{global}% \def\blx@tempe{global}% + \blx@kv@setkeys{blx@assignrefcontextmeta}{#2}% \blx@kv@setkeys{blx@assignrefcontext}{#2}% \def\do##1{% \listxadd\blx@assignedrefcontextkeywlist{##1}% @@ -9919,6 +10070,7 @@ \let\blx@tempc\@empty% \def\blx@tempd{global}% \def\blx@tempe{global}% + \blx@kv@setkeys{blx@assignrefcontextmeta}{#2}% \blx@kv@setkeys{blx@assignrefcontext}{#2}% \def\do##1{% \listxadd\blx@assignedrefcontextcatlist{##1}% @@ -9938,22 +10090,38 @@ \let\blx@tempc\@empty% \def\blx@tempd{global}% \def\blx@tempe{global}% + \blx@kv@setkeys{blx@assignrefcontextmeta}{#2}% \blx@kv@setkeys{blx@assignrefcontext}{#2}% \def\do##1{% \csxdef{blx@assignedrefcontextkeys#1@\the\c@refsection @##1}% {\blx@tempa/\blx@tempb/\blx@tempc/\blx@tempd/\blx@tempe}}% \docsvlist{#3}} +% This makes sure that named refcontexts set options first +% Note that the docs say that "name=default" selects the global default +% refcontext and this is because this won't set anything and the defaults +% in the above macros will take effect. +\blx@kv@defkey{blx@assignrefcontextmeta}{name}{% + \begingroup + \edef\blx@tempf{\endgroup% + \noexpand\blx@kv@setkeys{blx@assignrefcontext}{\csuse{blx@refcontext@name@#1}}}% + \blx@tempf} +\blx@kv@defkey{blx@assignrefcontextmeta}{nametemplates}{} +\blx@kv@defkey{blx@assignrefcontextmeta}{sorting}{} +\blx@kv@defkey{blx@assignrefcontextmeta}{sortingnamekeytemplatename}{} +\blx@kv@defkey{blx@assignrefcontextmeta}{labelprefix}{} +\blx@kv@defkey{blx@assignrefcontextmeta}{uniquenametemplatename}{} +\blx@kv@defkey{blx@assignrefcontextmeta}{labelalphanametemplatename}{} + % Meta option to set all name template options +\blx@kv@defkey{blx@assignrefcontext}{name}{} \blx@kv@defkey{blx@assignrefcontext}{nametemplates}{% \def\blx@tempb{#1}% \def\blx@tempd{#1}% \def\blx@tempe{#1}} - \blx@kv@defkey{blx@assignrefcontext}{sorting}{\def\blx@tempa{#1}} \blx@kv@defkey{blx@assignrefcontext}{sortingnamekeytemplatename}{\def\blx@tempb{#1}} -\blx@kv@defkey{blx@assignrefcontext}{labelprefix}{% - \edef\blx@tempc{\blx@mdfivesum{#1}}} +\blx@kv@defkey{blx@assignrefcontext}{labelprefix}{\edef\blx@tempc{\blx@mdfivesum{#1}}} \blx@kv@defkey{blx@assignrefcontext}{uniquenametemplatename}{\def\blx@tempd{#1}} \blx@kv@defkey{blx@assignrefcontext}{labelalphanametemplatename}{\def\blx@tempe{#1}} @@ -10408,7 +10576,7 @@ {\blx@error {Category '#1' not declared} {Use \string\DeclareBibliographyCategory\space to declare}} - {\AfterPreamble{% + {\blx@AfterPreamble{% \blx@xsanitizeafter{\forcsvlist{\blx@addtocategory{#1}}}{#2}}}} % {}{,...} @@ -10692,6 +10860,7 @@ \blx@citation@all} \def\blx@citation@all{% + \blx@auxwrite\@mainaux{}{\string\abx@aux@nociteall}% \ifbool{citerequest} {\blx@bibreq{*}% \global\csletcs @@ -10702,6 +10871,9 @@ {}} {}} +\def\abx@aux@nociteall{% + \listgadd\blx@nocites{*}} + \protected\def\blx@bibreq#1{% \begingroup \blx@xmlsanitizeafter{\def\blx@tempa}{#1}% @@ -10746,7 +10918,7 @@ I'm ignoring the new definition}}} {\global\cslet{blx@set@\the\c@refsection @\blx@tempa}\blx@tempb \edef\blx@tempa{% - \AfterPreamble{\blx@setreq{\blx@tempa}{\blx@tempb}}}% + \blx@AfterPreamble{\blx@setreq{\blx@tempa}{\blx@tempb}}}% \blx@tempa}% \endgroup \@esphack} @@ -11468,7 +11640,7 @@ \def\blx@nocite#1{% \@bsphack - \AfterPreamble{% + \blx@AfterPreamble{% \ifstrequal{*}{#1} {\blx@nocitation@all} {\blx@xsanitizeafter{\forcsvlist\blx@nocite@do}{#1}}}% @@ -15272,34 +15444,75 @@ \csdef{blx@opt@casechanger@auto}{% - \RequirePackage{expl3}[2020/04/06]% - \@ifpackagelater{expl3}{2020/04/06} - {\blx@info{expl3\MessageBreak\csuse{ver@expl3.sty}\MessageBreak - is new enough (at least 2020/04/06),\MessageBreak - setting 'casechanger=expl3'}% - \csuse{blx@opt@casechanger@expl3}} - {\blx@info{expl3\MessageBreak\csuse{ver@expl3.sty}\MessageBreak - is too old (older than 2020/04/06),\MessageBreak - setting 'casechanger=latex2e'}% + \ifdefstring{\blx@texencoding}{utf8} + {\blx@info@noline{Document encoding is UTF8 ...}% + \RequirePackage{expl3}[2020/04/06]% + \@ifpackagelater{expl3}{2020/04/06} + {\blx@info@noline{... and expl3\MessageBreak\csuse{ver@expl3.sty}\MessageBreak + is new enough (at least 2020/04/06),\MessageBreak + setting 'casechanger=expl3'}% + \csuse{blx@opt@casechanger@expl3}} + {\blx@info@noline{... but expl3\MessageBreak\csuse{ver@expl3.sty}\MessageBreak + is too old (older than 2020/04/06),\MessageBreak + setting 'casechanger=latex2e'}% + \csuse{blx@opt@casechanger@latex2e}}} + {\blx@info@noline{% + Document encoding not detected as UTF8.\MessageBreak + Setting 'casechanger=latex2e'}% \csuse{blx@opt@casechanger@latex2e}}} \csdef{blx@opt@casechanger@latex2e}{% - \blx@inputonce{blx-case-latex2e.def} - {LaTeX2e (legacy) case changing code} - {}{}{}{}} + \RequirePackage{blx-case-latex2e}} \csletcs{blx@opt@casechanger@2e}{blx@opt@casechanger@latex2e} -% Apparently neither \input nor \blx@inputonce ever pops the -% \ExplSyntaxOff from \ProvidesExplFile, so we do that ourselves. \csdef{blx@opt@casechanger@expl3}{% - \blx@inputonce{blx-case-expl3.def} - {expl3 case changing code} - {}{\ExplSyntaxOff}{}{}} + \ifdefstring{\blx@texencoding}{utf8} + {} + {\blx@warning@noline{% + The expl3 case changer code should only be used\MessageBreak + with UTF-8 encoding.\MessageBreak + But the document encoding was detected as + '\blx@texencoding'.\MessageBreak + Case changing macros may break\MessageBreak + if used with non-ASCII characters}}% + \RequirePackage{blx-case-expl3}} \csletcs{blx@opt@casechanger@3}{blx@opt@casechanger@expl3} % default to auto \csletcs{blx@deferoption@casechanger}{blx@opt@casechanger@auto} +% This is a bit unfortunate, but we need some more definitions after +% loading the case changing code. +\def\blx@casechange@postload{% + % Language fallback, in order: + % * explicit option language=, which overrides everything + % * langid field of entry + % * babel/polyglossia lang + % * main document lang (we should never reach this) + % * (we should *definitely* never reach this) + % Everything here is expandable so that + % \blx@mksc@lang expands to the language name. + \def\blx@mksc@lang{% + \ifundef\blx@forcelanguagename + {\ifundef\abx@field@langid + {\ifundef\blx@languagename + {\ifundef\blx@main@language + {} + {\blx@main@language}} + {\blx@languagename}} + {\abx@field@langid}} + {\blx@forcelanguagename}}% + % + \DeclareCaseLangs{% + american,british,canadian, + english,USenglish,UKenglish, + australian,newzealand}% + % Textcase defines \NoCaseChange as \let\NoCaseChange\@firstofone + \ifundef\NoCaseChange + {\let\NoCaseChange\@firstofone} + {}} +% That's it for the case change code + % Set defaults \blx@kv@setkeys{blx@opt@ldt}{style=numeric} \blx@kv@setkeys{blx@opt@pre}{% @@ -15340,43 +15553,6 @@ % Process load-time options \ProcessOptions* -% this ultimately loads either -% blx-case-expl3.def or blx-case-latex2e.def -\blx@deferoption@casechanger - -% This is a bit unfortunate, but we need some more definitions here. - -% Language fallback, in order: -% * explicit option language=, which overrides everything -% * langid field of entry -% * babel/polyglossia lang -% * main document lang (we should never reach this) -% * (we should *definitely* never reach this) -% Everything here is expandable so that -% \blx@mksc@lang expands to the language name. -\def\blx@mksc@lang{% - \ifundef\blx@forcelanguagename - {\ifundef\abx@field@langid - {\ifundef\blx@languagename - {\ifundef\blx@main@language - {} - {\blx@main@language}} - {\blx@languagename}} - {\abx@field@langid}} - {\blx@forcelanguagename}} - -\DeclareCaseLangs{% - american,british,canadian, - english,USenglish,UKenglish, - australian,newzealand} - - -% Textcase defines \NoCaseChange as \let\NoCaseChange\@firstofone -\ifundef\NoCaseChange - {\let\NoCaseChange\@firstofone} - {} - -% That's it for the case change code % Switch to BibTeX support if requested \iftoggle{blx@bibtex} @@ -15542,6 +15718,10 @@ \AtBeginDocument{% \blx@auxwrite\@mainaux{}{\string\abx@aux@refcontext{\blx@refcontext@context}} \blx@checkencoding + % this ultimately loads either + % blx-case-expl3.def or blx-case-latex2e.def + \blx@deferoption@casechanger + \blx@casechange@postload \if@filesw \blx@ctrlwrite \fi diff --git a/macros/latex/contrib/biblatex/latex/blx-bibtex.def b/macros/latex/contrib/biblatex/latex/blx-bibtex.def index 03d6781131..956b4708c5 100644 --- a/macros/latex/contrib/biblatex/latex/blx-bibtex.def +++ b/macros/latex/contrib/biblatex/latex/blx-bibtex.def @@ -215,6 +215,7 @@ \patchcmd{\blx@bblinput}{\blx@bblfile}{\blx@bblfile\blx@bblsecs}{}{} + \def\blx@bblfile{% \blx@secinit \begingroup @@ -227,13 +228,18 @@ \blx@ifsigned{\blx@auxfile}{bbl} {\InputIfFileExists{\blx@auxfile.bbl} {\blx@info@noline{... file '\blx@auxfile.bbl' found}% - \global\toggletrue{blx@bbldone}} + \global\toggletrue{blx@bbldone}% + \blx@generate@bbl@mdfivesum@found{\blx@auxfile.bbl}} {\blx@info@noline{... file '\blx@auxfile.bbl' not found}% \typeout{No file \blx@auxfile.bbl.}% - \global\togglefalse{blx@bbldone}}} + \global\togglefalse{blx@bbldone}% + \blx@generate@bbl@mdfivesum@notfound}} {}% \blx@bblend \endgroup + % Check if Biber rerun was not carried out. + % If so, ask for it again. + \blx@check@bbl@rerun@mdfivesum \csnumgdef{blx@labelnumber@\the\c@refsection}{0}} \def\blx@bblsecs{% diff --git a/macros/latex/contrib/biblatex/latex/blx-case-expl3.def b/macros/latex/contrib/biblatex/latex/blx-case-expl3.def deleted file mode 100644 index e9b7f23289..0000000000 --- a/macros/latex/contrib/biblatex/latex/blx-case-expl3.def +++ /dev/null @@ -1,271 +0,0 @@ -\RequirePackage{expl3}[2020/04/06] -\RequirePackage{xparse} -\ProvidesExplFile {blx-case-expl3} {\abx@date} {\abx@version} - {expl3 case changing code for biblatex} - -% Map for babel/polyglossia names -% to BCP-47-like l3text names. -% We only need maps for l3text names that do something -% as of 2020/04/06 those names are -% az, de-alt, el, lt, nl, tr. -% biblatex currently only supports dutch, greek and turkish -% so we only map those. -% de-alt is optional and still unusual, so *we* don't map it, -% but a user could map it themselves. - -\prop_new:N \l__biblatex_babel_to_pseudobcp_prop - -\cs_generate_variant:Nn \msg_info:nnnnn { nnnxn } - -\cs_new_protected:Npn \biblatex_maplang_babel_to_pseudobcp:nn #1 #2 - { - \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1} - { - \msg_info:nnnxn { biblatex } - { overwrite-babel-to-pseudobcp-map } - {#1} - {\prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1}} - {#2} - } - \prop_put:Nnn \l__biblatex_babel_to_pseudobcp_prop {#1} {#2} - } - -\NewDocumentCommand \DeclareBabelToExplLanguageMapping {mm} - { - \biblatex_maplang_babel_to_pseudobcp:nn {#1} {#2} - } - -\cs_generate_variant:Nn \msg_info:nnnn { nnnx } - -\cs_new_protected:Npn \biblatex_unmaplang_babel_to_pseudobcp:n #1 - { - \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1} - { - \msg_info:nnnx { biblatex } - { remove-babel-to-pseudobcp-map } - {#1} - { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1} } - } - \prop_remove:Nn \l__biblatex_babel_to_pseudobcp_prop {#1} - } - -\NewDocumentCommand \UndeclareBabelToExplLanguageMapping {m} - { - \str_if_eq:nnTF {#1} {*} - { \prop_clear:N \l__biblatex_babel_to_pseudobcp_prop } - { \biblatex_unmaplang_babel_to_pseudobcp:n {#1} } - } - -% Don't put this into biblatex.sty, since -% \DeclareBabelToExplLanguageMapping has no equivalent in the LaTeX2e -% code. -\DeclareBabelToExplLanguageMapping{dutch}{nl} -\DeclareBabelToExplLanguageMapping{greek}{el} -\DeclareBabelToExplLanguageMapping{turkish}{tr} - -% Our copy of \l_text_titlecase_check_letter_bool -\bool_new:N \l_biblatex_titlecase_check_letter_bool -% Just to be clear: unlike l3text our default is "false" -\bool_set_false:N \l_biblatex_titlecase_check_letter_bool - -% Helper macro to avoid unnecessary repetition of the same structure -% {} -% {}{} -% We use that \prop_item:Nn is empty if the item is not present -% and that \text_...:nn becomes \text_...:n if the first argument -% is empty. -\cs_new_protected:Npn \__biblatex_text_makeconverter:nnn #1 #2 #3 - { - \group_begin: - \bool_if_exist:NTF \l_text_titlecase_check_letter_bool - { - \bool_set_eq:NN \l_text_titlecase_check_letter_bool - \l_biblatex_titlecase_check_letter_bool - } - { - % should we raise an error or at least issue a warning here? - } - \use:c { text_#1:nn } - { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#2} } {#3} - \group_end: - } - - -\cs_new:Npn \biblatex_text_lowercase:nn #1 #2 - { - \__biblatex_text_makeconverter:nnn {lowercase} {#1} {#2} - } - -\cs_generate_variant:Nn \biblatex_text_lowercase:nn { Vn } - -\cs_new:Npn \biblatex_text_lowercase:n #1 - { - \biblatex_text_lowercase:Vn \blx@languagename {#1} - } - -\cs_set_eq:NN \blx@maketext@lowercase \biblatex_text_lowercase:n - - -\cs_new:Npn \biblatex_text_uppercase:nn #1 #2 - { - \__biblatex_text_makeconverter:nnn {uppercase} {#1} {#2} - } - -\cs_generate_variant:Nn \biblatex_text_uppercase:nn { Vn } - -\cs_new:Npn \biblatex_text_uppercase:n #1 - { - \biblatex_text_uppercase:Vn \blx@languagename {#1} - } - -\cs_set_eq:NN \blx@maketext@uppercase \biblatex_text_uppercase:n - - -\cs_new:Npn \biblatex_text_makecapital:nn #1 #2 - { - \__biblatex_text_makeconverter:nnn {titlecase_first} {#1} {#2} - } - -\cs_generate_variant:Nn \biblatex_text_makecapital:nn { Vn } - -\cs_new:Npn \biblatex_text_makecapital:n #1 - { - \biblatex_text_makecapital:Vn \blx@languagename {#1} - } - -\cs_set_eq:NN \blx@maketext@makecapital \biblatex_text_makecapital:n - -\NewDocumentCommand \MakeCapital {m} - { - \biblatex_text_makecapital:n {#1} - } - - - -% BibTeX to expl3 case protection code by Joseph Wright -% https://github.com/plk/biblatex/issues/960#issuecomment-578435859 -% and Bruno Le Floch -% https://github.com/moewew/biblatex/commit/c485f1b8079d56497b17343d7883b8fcd42f961a#r39225533 -\tl_put_right:Nn \l_text_expand_exclude_tl { \NoCaseChange } - -\tl_put_right:Nn \l_text_case_exclude_arg_tl { \NoCaseChange } - -\cs_new:Npn \biblatex_text_bibtex_to_expl:n #1 - { - \__biblatex_text_bibtex_loop:w #1 - { \q_recursion_tail } \q_recursion_stop - } - -\cs_new:Npn \__biblatex_text_bibtex_loop:w #1 # - { - \exp_not:n {#1} - \__biblatex_text_bibtex_group:n - } - -\cs_new:Npn \__biblatex_text_bibtex_group:n #1 - { - \quark_if_recursion_tail_stop:n {#1} - { - \bool_lazy_and:nnTF - { \tl_if_head_is_N_type_p:n {#1} } - { \exp_after:wN \token_if_cs_p:N \tl_head:w #1 \q_stop } - { \exp_not:n {#1} } - { \exp_not:n { \NoCaseChange {#1} } } - } - \__biblatex_text_bibtex_loop:w - } - -\cs_new_eq:NN \biblatex_text_sentencecase_preprocess:n - \biblatex_text_bibtex_to_expl:n - - -% By default we emulate BibTeX's brace case protection rules -% but the user can turn that off for a more sane behaviour -% that only relies on \NoCaseChange. -\DeclareBiblatexOption{global,type,entry}[boolean]{bibtexcaseprotection}[true]{% - \str_case:nnF {#1} - { - { true } - { - \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n - \biblatex_text_bibtex_to_expl:n - } - { false } - { - \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n - \use:n - } - } - { - \msg_error:nnn { biblatex } { invalid-value-bibtexcaseprotection } - {#1} - } -} - - -\cs_new:Npn \biblatex_text_sentencecase:nn #1 #2 - { - \__biblatex_text_makeconverter:nnn {titlecase} {#1} {#2} - } - - -\cs_generate_variant:Nn \clist_if_in:NnTF { NxTF } - -\cs_generate_variant:Nn \biblatex_text_sentencecase:nn { Vo, xo } - -% If \DeclareCaseLangs says we should apply sentence casing, -% we go for it and pass the language along to the sentence casing macro. -% Preprocess is either the BibTeX-to-expl3 brace translator -% or \@firstofone (do nothing), -% we need to expand once to get rid of the latter. -\NewDocumentCommand \MakeSentenceCase {sm} - { - \IfBooleanTF {#1} - { - \clist_if_in:NxTF - \l__biblatex_caselangs_clist { \blx@mksc@lang } - { - \biblatex_text_sentencecase:xo { \blx@mksc@lang } - { \biblatex_text_sentencecase_preprocess:n {#2} } - } - {#2} - } - { - \biblatex_text_sentencecase:Vo \blx@languagename - { \biblatex_text_sentencecase_preprocess:n {#2} } - } - } - - -\clist_new:N \l__biblatex_caselangs_clist - -% {} -\NewDocumentCommand \DeclareCaseLangs {sm} - { - \IfBooleanF {#1} - { \clist_clear:N \l__biblatex_caselangs_clist } - \clist_put_left:Nn \l__biblatex_caselangs_clist {#2} - } - -% \DeclareCaseLangs invocation is in biblatex.sty - - -\NewDocumentCommand \ifcaselang {O{\blx@languagename}} - { - \clist_if_in:NxTF \l__biblatex_caselangs_clist {#1} - } - - - -\msg_new:nnnn { biblatex } { invalid-value-bibtexcaseprotection } - { Invalid~value~'#1'~for~option~'bibtexcaseprotection'. } - { Valid~values~for~'bibtexcaseprotection'~are~'true'~and~'false'. } - -\msg_new:nnn { biblatex } { remove-babel-to-pseudobcp-map } - { Removing~babel->l3text~language~mapping~for~'#1'~to~'#2'. } - -\msg_new:nnn { biblatex } { overwrite-babel-to-pseudobcp-map } - { Overwriting~babel->l3text~language~mapping~for~'#1'~from~ - '#2'~to~'#3'. } - -\endinput diff --git a/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty b/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty new file mode 100644 index 0000000000..e90a4a7c11 --- /dev/null +++ b/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty @@ -0,0 +1,289 @@ +\RequirePackage{expl3}[2020/04/06] +\RequirePackage{xparse} +\ProvidesExplPackage {blx-case-expl3} {\abx@date} {\abx@version} + {expl3 case changing code for biblatex} + + +% helper macros to work around babel \languagename catcode weirdness +\cs_new:Npn \__biblatex_clist_put_detokenized_left:Nn #1 #2 + { + \clist_put_left:No #1 { \detokenize{#2} } + } + +\cs_generate_variant:Nn \__biblatex_clist_put_detokenized_left:Nn { Ne } + + +\prg_new_conditional:Npnn \__biblatex_clist_if_detokenized_in:Nn #1#2 { TF } + { + \clist_if_in:NoTF #1 { \detokenize{#2} } + {\prg_return_true:} + {\prg_return_false:} + } + +\prg_generate_conditional_variant:Nnn \__biblatex_clist_if_detokenized_in:Nn {Ne} {TF} + + + +% Map for babel/polyglossia names +% to BCP-47-like l3text names. +% We only need maps for l3text names that do something +% as of 2020/04/06 those names are +% az, de-alt, el, lt, nl, tr. +% biblatex currently only supports dutch, greek and turkish +% so we only map those. +% de-alt is optional and still unusual, so *we* don't map it, +% but a user could map it themselves. + +\prop_new:N \l__biblatex_babel_to_pseudobcp_prop + +\cs_generate_variant:Nn \msg_info:nnnnn { nnnxn } + +\cs_new_protected:Npn \biblatex_maplang_babel_to_pseudobcp:nn #1 #2 + { + \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1} + { + \msg_info:nnnxn { biblatex } + { overwrite-babel-to-pseudobcp-map } + {#1} + {\prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1}} + {#2} + } + \prop_put:Nnn \l__biblatex_babel_to_pseudobcp_prop {#1} {#2} + } + +\NewDocumentCommand \DeclareBabelToExplLanguageMapping {mm} + { + \biblatex_maplang_babel_to_pseudobcp:nn {#1} {#2} + } + +\cs_generate_variant:Nn \msg_info:nnnn { nnnx } + +\cs_new_protected:Npn \biblatex_unmaplang_babel_to_pseudobcp:n #1 + { + \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1} + { + \msg_info:nnnx { biblatex } + { remove-babel-to-pseudobcp-map } + {#1} + { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1} } + } + \prop_remove:Nn \l__biblatex_babel_to_pseudobcp_prop {#1} + } + +\NewDocumentCommand \UndeclareBabelToExplLanguageMapping {m} + { + \str_if_eq:nnTF {#1} {*} + { \prop_clear:N \l__biblatex_babel_to_pseudobcp_prop } + { \biblatex_unmaplang_babel_to_pseudobcp:n {#1} } + } + +% Don't put this into biblatex.sty, since +% \DeclareBabelToExplLanguageMapping has no equivalent in the LaTeX2e +% code. +\DeclareBabelToExplLanguageMapping{dutch}{nl} +\DeclareBabelToExplLanguageMapping{greek}{el} +\DeclareBabelToExplLanguageMapping{turkish}{tr} + +% Our copy of \l_text_titlecase_check_letter_bool +\bool_new:N \l_biblatex_titlecase_check_letter_bool +% Just to be clear: unlike l3text our default is "false" +\bool_set_false:N \l_biblatex_titlecase_check_letter_bool + +% Helper macro to avoid unnecessary repetition of the same structure +% {} +% {}{} +% We use that \prop_item:Nn is empty if the item is not present +% and that \text_...:nn becomes \text_...:n if the first argument +% is empty. +\cs_new_protected:Npn \__biblatex_text_makeconverter:nnn #1 #2 #3 + { + \group_begin: + \bool_if_exist:NTF \l_text_titlecase_check_letter_bool + { + \bool_set_eq:NN \l_text_titlecase_check_letter_bool + \l_biblatex_titlecase_check_letter_bool + } + { + % should we raise an error or at least issue a warning here? + } + \use:c { text_#1:nn } + { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#2} } {#3} + \group_end: + } + + +\cs_new:Npn \biblatex_text_lowercase:nn #1 #2 + { + \__biblatex_text_makeconverter:nnn {lowercase} {#1} {#2} + } + +\cs_generate_variant:Nn \biblatex_text_lowercase:nn { Vn } + +\cs_new:Npn \biblatex_text_lowercase:n #1 + { + \biblatex_text_lowercase:Vn \blx@languagename {#1} + } + +\cs_set_eq:NN \blx@maketext@lowercase \biblatex_text_lowercase:n + + +\cs_new:Npn \biblatex_text_uppercase:nn #1 #2 + { + \__biblatex_text_makeconverter:nnn {uppercase} {#1} {#2} + } + +\cs_generate_variant:Nn \biblatex_text_uppercase:nn { Vn } + +\cs_new:Npn \biblatex_text_uppercase:n #1 + { + \biblatex_text_uppercase:Vn \blx@languagename {#1} + } + +\cs_set_eq:NN \blx@maketext@uppercase \biblatex_text_uppercase:n + + +\cs_new:Npn \biblatex_text_makecapital:nn #1 #2 + { + \__biblatex_text_makeconverter:nnn {titlecase_first} {#1} {#2} + } + +\cs_generate_variant:Nn \biblatex_text_makecapital:nn { Vn } + +\cs_new:Npn \biblatex_text_makecapital:n #1 + { + \biblatex_text_makecapital:Vn \blx@languagename {#1} + } + +\cs_set_eq:NN \blx@maketext@makecapital \biblatex_text_makecapital:n + +\NewDocumentCommand \MakeCapital {m} + { + \biblatex_text_makecapital:n {#1} + } + + + +% BibTeX to expl3 case protection code by Joseph Wright +% https://github.com/plk/biblatex/issues/960#issuecomment-578435859 +% and Bruno Le Floch +% https://github.com/moewew/biblatex/commit/c485f1b8079d56497b17343d7883b8fcd42f961a#r39225533 +\tl_put_right:Nn \l_text_expand_exclude_tl { \NoCaseChange } + +\tl_put_right:Nn \l_text_case_exclude_arg_tl { \NoCaseChange } + +\cs_new:Npn \biblatex_text_bibtex_to_expl:n #1 + { + \__biblatex_text_bibtex_loop:w #1 + { \q_recursion_tail } \q_recursion_stop + } + +\cs_new:Npn \__biblatex_text_bibtex_loop:w #1 # + { + \exp_not:n {#1} + \__biblatex_text_bibtex_group:n + } + +\cs_new:Npn \__biblatex_text_bibtex_group:n #1 + { + \quark_if_recursion_tail_stop:n {#1} + { + \bool_lazy_and:nnTF + { \tl_if_head_is_N_type_p:n {#1} } + { \exp_after:wN \token_if_cs_p:N \tl_head:w #1 \q_stop } + { \exp_not:n {#1} } + { \exp_not:n { \NoCaseChange {#1} } } + } + \__biblatex_text_bibtex_loop:w + } + +\cs_new_eq:NN \biblatex_text_sentencecase_preprocess:n + \biblatex_text_bibtex_to_expl:n + + +% By default we emulate BibTeX's brace case protection rules +% but the user can turn that off for a more sane behaviour +% that only relies on \NoCaseChange. +\DeclareBiblatexOption{global,type,entry}[boolean]{bibtexcaseprotection}[true]{% + \str_case:nnF {#1} + { + { true } + { + \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n + \biblatex_text_bibtex_to_expl:n + } + { false } + { + \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n + \use:n + } + } + { + \msg_error:nnn { biblatex } { invalid-value-bibtexcaseprotection } + {#1} + } +} + + +\cs_new:Npn \biblatex_text_sentencecase:nn #1 #2 + { + \__biblatex_text_makeconverter:nnn {titlecase} {#1} {#2} + } + + +\cs_generate_variant:Nn \biblatex_text_sentencecase:nn { Vo, xo } + +% If \DeclareCaseLangs says we should apply sentence casing, +% we go for it and pass the language along to the sentence casing macro. +% Preprocess is either the BibTeX-to-expl3 brace translator +% or \@firstofone (do nothing), +% we need to expand once to get rid of the latter. +\NewDocumentCommand \MakeSentenceCase {sm} + { + \IfBooleanTF {#1} + { + \__biblatex_clist_if_detokenized_in:NeTF + \l__biblatex_caselangs_clist { \blx@mksc@lang } + { + \biblatex_text_sentencecase:xo { \blx@mksc@lang } + { \biblatex_text_sentencecase_preprocess:n {#2} } + } + {#2} + } + { + \biblatex_text_sentencecase:Vo \blx@languagename + { \biblatex_text_sentencecase_preprocess:n {#2} } + } + } + + +\clist_new:N \l__biblatex_caselangs_clist + +% {} +\NewDocumentCommand \DeclareCaseLangs {sm} + { + \IfBooleanF {#1} + { \clist_clear:N \l__biblatex_caselangs_clist } + \__biblatex_clist_put_detokenized_left:Ne + \l__biblatex_caselangs_clist {#2} + } + +% \DeclareCaseLangs invocation is in biblatex.sty + +\NewDocumentCommand \ifcaselang {O{\blx@languagename}} + { + \__biblatex_clist_if_detokenized_in:NeTF \l__biblatex_caselangs_clist {#1} + } + + +\msg_new:nnnn { biblatex } { invalid-value-bibtexcaseprotection } + { Invalid~value~'#1'~for~option~'bibtexcaseprotection'. } + { Valid~values~for~'bibtexcaseprotection'~are~'true'~and~'false'. } + +\msg_new:nnn { biblatex } { remove-babel-to-pseudobcp-map } + { Removing~babel->l3text~language~mapping~for~'#1'~to~'#2'. } + +\msg_new:nnn { biblatex } { overwrite-babel-to-pseudobcp-map } + { Overwriting~babel->l3text~language~mapping~for~'#1'~from~ + '#2'~to~'#3'. } + +\endinput diff --git a/macros/latex/contrib/biblatex/latex/blx-case-latex2e.def b/macros/latex/contrib/biblatex/latex/blx-case-latex2e.def deleted file mode 100644 index 85641d2e66..0000000000 --- a/macros/latex/contrib/biblatex/latex/blx-case-latex2e.def +++ /dev/null @@ -1,290 +0,0 @@ -\ProvidesFile{blx-case-latex2e.def} -[\abx@cptid] - -% we don't have l3text's (pseudo)BCP47 language codes here -\newrobustcmd*{\DeclareBabelToExplLanguageMapping}[2]{% - \blx@warning{The command '\string\DeclareBabelToExplLanguageMapping'% - \MessageBreak - is only available with the expl3 case changing\MessageBreak - implementation ('casechanger=expl3').\MessageBreak - Ignoring}} - -\newrobustcmd*{\UndeclareBabelToExplLanguageMapping}[1]{% - \blx@warning{The command '\string\UndeclareBabelToExplLanguageMapping'% - \MessageBreak - is only available with the expl3 case changing\MessageBreak - implementation ('casechanger=expl3').\MessageBreak - Ignoring}} - -\def\blx@maketext@lowercase{\MakeLowercase} - -\def\blx@maketext@uppercase{\MakeUppercase} - -\def\blx@maketext@makecapital{\MakeCapital} - -% {} -\newrobustcmd{\MakeCapital}[1]{% - \begingroup - \blx@mkcp@init - \protected@edef\blx@tempa{#1}% - \expandafter\blx@mkcp@parse\blx@tempa\@empty\blx@mkcp@end} - -\def\blx@mkcp@init{% - \def\blx@mkcp@iec{\noexpand\blx@mkcp@iec\noexpand}% - \def\blx@mkcp@bbl{\noexpand\blx@mkcp@bbl\noexpand}% - \def\blx@mkcp@sgl{\noexpand\blx@mkcp@sgl\noexpand}% - \def\blx@mkcp@dbl{\noexpand\blx@mkcp@dbl\noexpand}% - \def\do##1{\def##1{\blx@mkcp@sgl##1}}\abx@dosingleaccents - \def\do##1{\def##1{\blx@mkcp@dbl##1}}\abx@dodoubleaccents - \def\IeC##1{\blx@mkcp@iec\IeC{##1}}% - \def\@tabacckludge##1{% - \expandafter\blx@mkcp@sgl\csname\string##1\endcsname}} - -\begingroup -\catcode`\"=\active -\gappto\blx@mkcp@init{% - \ifnum\catcode`\"=\active - \def"#1{\blx@mkcp@bbl"\noexpand#1}% - \fi} -\endgroup - -\def\blx@mkcp@parse{% - \futurelet\@let@token\blx@mkcp@eval} - -\long\def\blx@mkcp@eval{% - \ifx\@let@token\blx@mkcp@iec - \expandafter\blx@mkcp@getiec - \fi - \ifx\@let@token\blx@mkcp@bbl - \expandafter\blx@mkcp@gettwo - \fi - \ifx\@let@token\blx@mkcp@sgl - \expandafter\blx@mkcp@gettwo - \fi - \ifx\@let@token\blx@mkcp@dbl - \expandafter\blx@mkcp@getthree - \fi - \blx@mkcp@case} - -\def\blx@mkcp@getiec#1\blx@mkcp@case#2#3#4{% - \blx@mkcp@case{#2#3{#4}}} - -\def\blx@mkcp@gettwo#1\blx@mkcp@case#2#3#4{% - \blx@mkcp@case{#2#3#4}} - -\def\blx@mkcp@getthree#1\blx@mkcp@case#2#3#4#5{% - \blx@mkcp@case{#2#3#4#5}} - -\long\def\blx@mkcp@case#1{% - \begingroup - \def\i{I}\def\j{J}% - \def\do##1##2{\let##1##2\do}% - \expandafter\do\@uclclist\relax{\relax\@gobble}% - \uppercase{\protected@edef\blx@tempa{\endgroup\blx@mkcp@end#1}}% - \blx@tempa} - -\protected\long\def\blx@mkcp@end#1\blx@mkcp@end{% - \let\blx@mkcp@iec\noexpand - \let\blx@mkcp@bbl\noexpand - \let\blx@mkcp@sgl\noexpand - \let\blx@mkcp@dbl\noexpand - \protected@edef\blx@tempa{\endgroup#1}% - \blx@tempa} - - -\DeclareBiblatexOption{global,type,entry}[boolean]{bibtexcaseprotection}[true]{% - \ifstrequal{#1}{true} - {} - {\ifstrequal{#1}{false} - {\blx@warning - {The option 'bibtexcaseprotection=false' is only\MessageBreak - available with expl3}} - {\blx@err@invopt{bibtexcaseprotection=#1} - {Valid values for 'bibtexcaseprotection' are 'true' and - 'false'\MessageBreak - (but 'false' only works with expl3 code)}}}} - -% {} -\newrobustcmd*{\MakeSentenceCase}{% - \@ifstar\blx@mksc@i\blx@mksc@ii} - -% \blx@cmksc@lang is defined in biblatex.sty -% it expands to the applicable language for the title field -\def\blx@mksc@i{% - \xifinlist\blx@mksc@lang\blx@cmksc@lang - {\blx@mksc@ii} - {\@firstofone}} - -\long\def\blx@mksc@ii#1{% - \begingroup - \let\blx@tempa\@empty - \let\blx@tempb\@empty - \blx@mksc@init - \protected@edef\@tempa{#1}% - \expandafter\blx@mksc@parse\@tempa\blx@mksc@end} - -\def\blx@mksc@init{% - \blx@mkcp@init - \def\blx@mkcp@nil{\noexpand\blx@mkcp@nil\noexpand}% - \def\i{\blx@mkcp@nil\i}\def\j{\blx@mkcp@nil\j}% - \def\do##1{% - \ifx##1\relax - \else - \def##1{\blx@mkcp@nil##1}% - \expandafter\do - \fi}% - \expandafter\do\@uclclist\relax} - -\def\blx@mksc@parse{% - \futurelet\@let@token\blx@mksc@eval} - -\let\blx@asttoken=* - -\def\blx@mksc@eval{% - \ifx\@let@token\blx@mksc@end - \expandafter\blx@mksc@end - \fi - \ifx\@let@token\bgroup - \expandafter\blx@mksc@group - \fi - \ifx\@let@token\@sptoken - \expandafter\blx@mksc@space - \fi - \ifx\@let@token\blx@mkcp@nil - \expandafter\blx@mksc@getone - \fi - \ifx\@let@token\blx@mkcp@iec - \expandafter\blx@mksc@getiec - \fi - \ifx\@let@token\blx@mkcp@bbl - \expandafter\blx@mksc@gettwo - \fi - \ifx\@let@token\blx@mkcp@sgl - \expandafter\blx@mksc@gettwo - \fi - \ifx\@let@token\blx@mkcp@dbl - \expandafter\blx@mksc@getthree - \fi - \ifx\@let@token\blx@asttoken - \expandafter\blx@mksc@cs - \fi - \if\noexpand\@let@token\relax - \expandafter\blx@mksc@cs - \fi - \blx@mksc@other} - -\def\blx@mksc@end#1\blx@mksc@end{% - \blx@mksc@eject - \let\blx@mkcp@nil\noexpand - \let\blx@mkcp@iec\noexpand - \let\blx@mkcp@bbl\noexpand - \let\blx@mkcp@sgl\noexpand - \let\blx@mkcp@dbl\noexpand - \let\MakeUppercase\relax - \let\MakeLowercase\relax - \protected@edef\blx@tempa{\endgroup\blx@tempa}% - \blx@tempa} - -\long\def\blx@mksc@group#1\blx@mksc@other#2{% - \futurelet\@let@token\blx@mksc@ingroup#2&{#2}% - \blx@mksc@endhead - \blx@mksc@parse} - -\long\def\blx@mksc@ingroup#1{% - \if\noexpand\@let@token\relax - \ifx\@let@token\blx@mkcp@sgl - \blx@mksc@nocase{{#2}}% - \else - \ifx\@let@token\blx@mkcp@dbl - \blx@mksc@nocase{{#2}}% - \else - \blx@mksc@locase{{#2}}% - \fi - \fi - \else - \blx@mksc@nocase{{#2}}% - \fi} - -\def\blx@mksc@space{\def\blx@mksc@space##1\blx@mksc@other} -\csuse{blx@mksc@space} {% - \blx@mksc@anycase{ }% - \blx@mksc@endhead - \blx@mksc@parse} - -\long\def\blx@mksc@cs#1\blx@mksc@other#2{% - \ifcat\noexpand~\noexpand#2% - \blx@mksc@locase{#2}% - \else - \blx@mksc@nocase{#2}% - \fi - \blx@mksc@endhead - \blx@mksc@parse} - -\def\blx@mksc@getiec#1\blx@mksc@other#2#3#4{% - \blx@mksc@other{#2#3{#4}}} - -\def\blx@mksc@getone#1\blx@mksc@other#2#3{% - \blx@mksc@other{#2#3}} - -\def\blx@mksc@gettwo#1\blx@mksc@other#2#3#4{% - \blx@mksc@other{#2#3#4}} - -\def\blx@mksc@getthree#1\blx@mksc@other#2#3#4#5{% - \blx@mksc@other{#2#3#4#5}} - -\long\def\blx@mksc@other#1{% - \blx@mksc@locase{#1}% - \blx@mksc@endhead - \blx@mksc@parse} - -\def\blx@mksc@locase{% - \appto\blx@tempb} - -\def\blx@mksc@nocase{% - \blx@mksc@eject - \appto\blx@tempa} - -\def\blx@mksc@anycase{% - \ifx\blx@tempb\@empty - \expandafter\appto - \expandafter\blx@tempa - \else - \expandafter\appto - \expandafter\blx@tempb - \fi} - -\def\blx@mksc@eject{% - \ifx\blx@tempb\@empty - \else - \eappto\blx@tempa{\noexpand\MakeLowercase{\expandonce\blx@tempb}}% - \let\blx@tempb\@empty - \fi} - -\def\blx@mksc@endhead{% - \ifx\blx@tempb\@empty - \else - \eappto\blx@tempa{\noexpand\MakeCapital{\expandonce\blx@tempb}}% - \let\blx@tempb\@empty - \fi - \let\blx@mksc@endhead\relax} - - - -% {} -\newrobustcmd*{\DeclareCaseLangs}{% - \@ifstar - {\blx@defcaselangs} - {\global\let\blx@cmksc@lang\@empty - \blx@defcaselangs}} - -\def\blx@defcaselangs#1{% - \ifblank{#1} - {} - {\forcsvlist{\listgadd\blx@cmksc@lang}{#1}}} - -% \DeclareCaseLangs invocation is in biblatex.sty - -\newrobustcmd*{\ifcaselang}[1][\blx@languagename]{% - \xifinlist{#1}\blx@cmksc@lang} - -\endinput diff --git a/macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty b/macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty new file mode 100644 index 0000000000..5aede0c0bb --- /dev/null +++ b/macros/latex/contrib/biblatex/latex/blx-case-latex2e.sty @@ -0,0 +1,326 @@ +\ProvidesPackage{blx-case-latex2e} +[\abx@cptid] + +% auxiliary macros +% babel's \languagename has weird catcodes, +% so we \detokenize our language names + +\def\blx@listgadd@switched#1#2{\listgadd{#2}{#1}} + +\ifundef\expanded + {\protected\def\blx@deifinlist#1{% + \begingroup + \edef\blx@tempa{\endgroup + \blx@deifinlist@i{#1}}% + \blx@tempa}% + \protected\def\blx@deifinlist@i#1{% + \expandafter\ifinlist\expandafter{\detokenize{#1}}}% + % + \protected\def\blx@listdxadd@switched#1{% + \begingroup + \edef\blx@tempa{\endgroup + \blx@listdxadd@switched@i{#1}}% + \blx@tempa}% + \protected\def\blx@listdxadd@switched@i#1{% + \expandafter\blx@listgadd@switched\expandafter{\detokenize{#1}}}} + {\def\blx@deifinlist#1{% + \expandafter\expandafter\expandafter\ifinlist + \expandafter\expandafter\expandafter{% + \expandafter\detokenize\expandafter{\expanded{#1}}}}% + % + \def\blx@listdxadd@switched#1{% + \expandafter\expandafter\expandafter\blx@listgadd@switched + \expandafter\expandafter\expandafter{% + \expandafter\detokenize\expandafter{\expanded{#1}}}}} + +\def\blx@listdxadd#1#2{\blx@listdxadd@switched{#2}{#1}} + + +% we don't have l3text's (pseudo)BCP47 language codes here +\newrobustcmd*{\DeclareBabelToExplLanguageMapping}[2]{% + \blx@warning{The command '\string\DeclareBabelToExplLanguageMapping'% + \MessageBreak + is only available with the expl3 case changing\MessageBreak + implementation ('casechanger=expl3').\MessageBreak + Ignoring}} + +\newrobustcmd*{\UndeclareBabelToExplLanguageMapping}[1]{% + \blx@warning{The command '\string\UndeclareBabelToExplLanguageMapping'% + \MessageBreak + is only available with the expl3 case changing\MessageBreak + implementation ('casechanger=expl3').\MessageBreak + Ignoring}} + +\def\blx@maketext@lowercase{\MakeLowercase} + +\def\blx@maketext@uppercase{\MakeUppercase} + +\def\blx@maketext@makecapital{\MakeCapital} + +% {} +\newrobustcmd{\MakeCapital}[1]{% + \begingroup + \blx@mkcp@init + \protected@edef\blx@tempa{#1}% + \expandafter\blx@mkcp@parse\blx@tempa\@empty\blx@mkcp@end} + +\def\blx@mkcp@init{% + \def\blx@mkcp@iec{\noexpand\blx@mkcp@iec\noexpand}% + \def\blx@mkcp@bbl{\noexpand\blx@mkcp@bbl\noexpand}% + \def\blx@mkcp@sgl{\noexpand\blx@mkcp@sgl\noexpand}% + \def\blx@mkcp@dbl{\noexpand\blx@mkcp@dbl\noexpand}% + \def\do##1{\def##1{\blx@mkcp@sgl##1}}\abx@dosingleaccents + \def\do##1{\def##1{\blx@mkcp@dbl##1}}\abx@dodoubleaccents + \def\IeC##1{\blx@mkcp@iec\IeC{##1}}% + \def\@tabacckludge##1{% + \expandafter\blx@mkcp@sgl\csname\string##1\endcsname}} + +\begingroup +\catcode`\"=\active +\gappto\blx@mkcp@init{% + \ifnum\catcode`\"=\active + \def"#1{\blx@mkcp@bbl"\noexpand#1}% + \fi} +\endgroup + +\def\blx@mkcp@parse{% + \futurelet\@let@token\blx@mkcp@eval} + +\long\def\blx@mkcp@eval{% + \ifx\@let@token\blx@mkcp@iec + \expandafter\blx@mkcp@getiec + \fi + \ifx\@let@token\blx@mkcp@bbl + \expandafter\blx@mkcp@gettwo + \fi + \ifx\@let@token\blx@mkcp@sgl + \expandafter\blx@mkcp@gettwo + \fi + \ifx\@let@token\blx@mkcp@dbl + \expandafter\blx@mkcp@getthree + \fi + \blx@mkcp@case} + +\def\blx@mkcp@getiec#1\blx@mkcp@case#2#3#4{% + \blx@mkcp@case{#2#3{#4}}} + +\def\blx@mkcp@gettwo#1\blx@mkcp@case#2#3#4{% + \blx@mkcp@case{#2#3#4}} + +\def\blx@mkcp@getthree#1\blx@mkcp@case#2#3#4#5{% + \blx@mkcp@case{#2#3#4#5}} + +\long\def\blx@mkcp@case#1{% + \begingroup + \def\i{I}\def\j{J}% + \def\do##1##2{\let##1##2\do}% + \expandafter\do\@uclclist\relax{\relax\@gobble}% + \uppercase{\protected@edef\blx@tempa{\endgroup\blx@mkcp@end#1}}% + \blx@tempa} + +\protected\long\def\blx@mkcp@end#1\blx@mkcp@end{% + \let\blx@mkcp@iec\noexpand + \let\blx@mkcp@bbl\noexpand + \let\blx@mkcp@sgl\noexpand + \let\blx@mkcp@dbl\noexpand + \protected@edef\blx@tempa{\endgroup#1}% + \blx@tempa} + + +\DeclareBiblatexOption{global,type,entry}[boolean]{bibtexcaseprotection}[true]{% + \ifstrequal{#1}{true} + {} + {\ifstrequal{#1}{false} + {\blx@warning + {The option 'bibtexcaseprotection=false' is only\MessageBreak + available with expl3}} + {\blx@err@invopt{bibtexcaseprotection=#1} + {Valid values for 'bibtexcaseprotection' are 'true' and + 'false'\MessageBreak + (but 'false' only works with expl3 code)}}}} + +% {} +\newrobustcmd*{\MakeSentenceCase}{% + \@ifstar\blx@mksc@i\blx@mksc@ii} + + +% \blx@cmksc@lang is defined in biblatex.sty +% it expands to the applicable language for the title field +\def\blx@mksc@i{% + \blx@deifinlist\blx@mksc@lang\blx@cmksc@lang + {\blx@mksc@ii} + {\@firstofone}} + +\long\def\blx@mksc@ii#1{% + \begingroup + \let\blx@tempa\@empty + \let\blx@tempb\@empty + \blx@mksc@init + \protected@edef\@tempa{#1}% + \expandafter\blx@mksc@parse\@tempa\blx@mksc@end} + +\def\blx@mksc@init{% + \blx@mkcp@init + \def\blx@mkcp@nil{\noexpand\blx@mkcp@nil\noexpand}% + \def\i{\blx@mkcp@nil\i}\def\j{\blx@mkcp@nil\j}% + \def\do##1{% + \ifx##1\relax + \else + \def##1{\blx@mkcp@nil##1}% + \expandafter\do + \fi}% + \expandafter\do\@uclclist\relax} + +\def\blx@mksc@parse{% + \futurelet\@let@token\blx@mksc@eval} + +\let\blx@asttoken=* + +\def\blx@mksc@eval{% + \ifx\@let@token\blx@mksc@end + \expandafter\blx@mksc@end + \fi + \ifx\@let@token\bgroup + \expandafter\blx@mksc@group + \fi + \ifx\@let@token\@sptoken + \expandafter\blx@mksc@space + \fi + \ifx\@let@token\blx@mkcp@nil + \expandafter\blx@mksc@getone + \fi + \ifx\@let@token\blx@mkcp@iec + \expandafter\blx@mksc@getiec + \fi + \ifx\@let@token\blx@mkcp@bbl + \expandafter\blx@mksc@gettwo + \fi + \ifx\@let@token\blx@mkcp@sgl + \expandafter\blx@mksc@gettwo + \fi + \ifx\@let@token\blx@mkcp@dbl + \expandafter\blx@mksc@getthree + \fi + \ifx\@let@token\blx@asttoken + \expandafter\blx@mksc@cs + \fi + \if\noexpand\@let@token\relax + \expandafter\blx@mksc@cs + \fi + \blx@mksc@other} + +\def\blx@mksc@end#1\blx@mksc@end{% + \blx@mksc@eject + \let\blx@mkcp@nil\noexpand + \let\blx@mkcp@iec\noexpand + \let\blx@mkcp@bbl\noexpand + \let\blx@mkcp@sgl\noexpand + \let\blx@mkcp@dbl\noexpand + \let\MakeUppercase\relax + \let\MakeLowercase\relax + \protected@edef\blx@tempa{\endgroup\blx@tempa}% + \blx@tempa} + +\long\def\blx@mksc@group#1\blx@mksc@other#2{% + \futurelet\@let@token\blx@mksc@ingroup#2&{#2}% + \blx@mksc@endhead + \blx@mksc@parse} + +\long\def\blx@mksc@ingroup#1{% + \if\noexpand\@let@token\relax + \ifx\@let@token\blx@mkcp@sgl + \blx@mksc@nocase{{#2}}% + \else + \ifx\@let@token\blx@mkcp@dbl + \blx@mksc@nocase{{#2}}% + \else + \blx@mksc@locase{{#2}}% + \fi + \fi + \else + \blx@mksc@nocase{{#2}}% + \fi} + +\def\blx@mksc@space{\def\blx@mksc@space##1\blx@mksc@other} +\csuse{blx@mksc@space} {% + \blx@mksc@anycase{ }% + \blx@mksc@endhead + \blx@mksc@parse} + +\long\def\blx@mksc@cs#1\blx@mksc@other#2{% + \ifcat\noexpand~\noexpand#2% + \blx@mksc@locase{#2}% + \else + \blx@mksc@nocase{#2}% + \fi + \blx@mksc@endhead + \blx@mksc@parse} + +\def\blx@mksc@getiec#1\blx@mksc@other#2#3#4{% + \blx@mksc@other{#2#3{#4}}} + +\def\blx@mksc@getone#1\blx@mksc@other#2#3{% + \blx@mksc@other{#2#3}} + +\def\blx@mksc@gettwo#1\blx@mksc@other#2#3#4{% + \blx@mksc@other{#2#3#4}} + +\def\blx@mksc@getthree#1\blx@mksc@other#2#3#4#5{% + \blx@mksc@other{#2#3#4#5}} + +\long\def\blx@mksc@other#1{% + \blx@mksc@locase{#1}% + \blx@mksc@endhead + \blx@mksc@parse} + +\def\blx@mksc@locase{% + \appto\blx@tempb} + +\def\blx@mksc@nocase{% + \blx@mksc@eject + \appto\blx@tempa} + +\def\blx@mksc@anycase{% + \ifx\blx@tempb\@empty + \expandafter\appto + \expandafter\blx@tempa + \else + \expandafter\appto + \expandafter\blx@tempb + \fi} + +\def\blx@mksc@eject{% + \ifx\blx@tempb\@empty + \else + \eappto\blx@tempa{\noexpand\MakeLowercase{\expandonce\blx@tempb}}% + \let\blx@tempb\@empty + \fi} + +\def\blx@mksc@endhead{% + \ifx\blx@tempb\@empty + \else + \eappto\blx@tempa{\noexpand\MakeCapital{\expandonce\blx@tempb}}% + \let\blx@tempb\@empty + \fi + \let\blx@mksc@endhead\relax} + + + +% {} +\newrobustcmd*{\DeclareCaseLangs}{% + \@ifstar + {\blx@defcaselangs} + {\global\let\blx@cmksc@lang\@empty + \blx@defcaselangs}} + +\def\blx@defcaselangs#1{% + \ifblank{#1} + {} + {\forcsvlist{\blx@listdxadd\blx@cmksc@lang}{#1}}} + +% \DeclareCaseLangs invocation is in biblatex.sty + +\newrobustcmd*{\ifcaselang}[1][\blx@languagename]{% + \blx@deifinlist{#1}\blx@cmksc@lang} + +\endinput diff --git a/macros/latex/contrib/biblatex/latex/blx-compat.def b/macros/latex/contrib/biblatex/latex/blx-compat.def index 546f16af43..46272f181f 100644 --- a/macros/latex/contrib/biblatex/latex/blx-compat.def +++ b/macros/latex/contrib/biblatex/latex/blx-compat.def @@ -351,5 +351,9 @@ Please use '\string\mkdaterangeisoextra'}% \mkdaterangeisoextra} +% 3.16 +% deprecate \mainlang for \textmainlang +% and \mkrelatedstring for \mkrelatedstringtext +\newcommand{\mkrelatedstring}{\mainlang} \endinput diff --git a/macros/latex/contrib/biblatex/latex/blx-dm.def b/macros/latex/contrib/biblatex/latex/blx-dm.def index 0667b577ae..cb23e20c5f 100644 --- a/macros/latex/contrib/biblatex/latex/blx-dm.def +++ b/macros/latex/contrib/biblatex/latex/blx-dm.def @@ -1464,7 +1464,7 @@ } } -\DeclareDatamodelConstraints[book,mvbook,mvcollection,mvreference]{ +\DeclareDatamodelConstraints[book,mvbook]{ \constraint[type=mandatory]{ \constraintfield{author} \constraintfield{title} @@ -1489,7 +1489,7 @@ } } -\DeclareDatamodelConstraints[collection,reference]{ +\DeclareDatamodelConstraints[collection,reference,mvcollection,mvreference]{ \constraint[type=mandatory]{ \constraintfield{editor} \constraintfield{title} @@ -1598,12 +1598,6 @@ \constraint[type=data, datatype=ismn]{ \constraintfield{ismn} } - \constraint[type=data, datatype=date]{ - \constraintfield{date} - \constraintfield{eventdate} - \constraintfield{origdate} - \constraintfield{urldate} - } \constraint[type=data, datatype=pattern, pattern=\regexp{(?:sf|sm|sn|pf|pm|pn|pp)}]{ \constraintfield{gender} } diff --git a/macros/latex/contrib/biblatex/latex/blx-unicode.def b/macros/latex/contrib/biblatex/latex/blx-unicode.def index 01009c028c..12eabfe98b 100644 --- a/macros/latex/contrib/biblatex/latex/blx-unicode.def +++ b/macros/latex/contrib/biblatex/latex/blx-unicode.def @@ -32,6 +32,20 @@ \closein\blx@bcfin \endgroup +% Second part of workaround for odd XeTeX/babel-french behaviour +% https://github.com/plk/biblatex/issues/979 +% fix by Ulrike Fischer +% https://tex.stackexchange.com/a/544914/. +% The first bit lives in biblatex.sty. +% At some point we may want to consider providing a +% blx-unicode-xetex and a blx-unicode-lualatex +% both loading a blx-unicode-generic. +% For now this test is enough. +\ifundef\XeTeXrevision + {} + {\providerobustcmd*{\textnohyphenation}[1]{% + \bgroup\nohyphenation#1\egroup^^^^200b}} + \appto\blx@setfrcodes{% % … should probably have dot spacefactor, but pdfLaTeX % makes it a period, so we have this here for consistency diff --git a/macros/latex/contrib/biblatex/latex/lbx/basque.lbx b/macros/latex/contrib/biblatex/latex/lbx/basque.lbx new file mode 100644 index 0000000000..6263081e97 --- /dev/null +++ b/macros/latex/contrib/biblatex/latex/lbx/basque.lbx @@ -0,0 +1,480 @@ +\ProvidesFile{basque.lbx} +[\abx@lbxid] + +\DeclareRedundantLanguages{basque}{basque} + +\DeclareBibliographyExtras{% + \protected\def\bibrangedash{\mbox{-}}% non-breaking hyphen + \let\finalandcomma=\empty + \let\finalandsemicolon=\empty + \def\mkbibordinal{\mkbibmascord}% + \providecommand*{\sptext}{\textsuperscript}% \sptext -> spanish.ldf (babel) + %\protected\def\mkbibmascord#1{\stripzeros{#1}\sptext{o}}% + \protected\def\mkbibmascord#1{\stripzeros{#1}\adddot}% + %\protected\def\mkbibfemord#1{\stripzeros{#1}\sptext{a}}% + \protected\def\mkbibfemord#1{\stripzeros{#1}\adddot}% + \protected\def\mkbibneutord{\mkbibmascord}% + \protected\def\mkbibdatelong#1#2#3{% + \iffieldundef{#3} + {} + {\stripzeros{\thefield{#3}}% + \iffieldundef{#2}{}{\nobreakspace de\space}}% + \iffieldundef{#2} + {} + {\mkbibmonth{\thefield{#2}}% + \iffieldundef{#1}{}{\nobreakspace de\space}}% + \iffieldbibstring{#1} + {\bibstring{\thefield{#1}}} + {\dateeraprintpre{#1}\mkyearzeros{\thefield{#1}}}}% + \protected\def\mkbibdateshort#1#2#3{% + \iffieldundef{#1} + {} + {\mkdayzeros{\thefield{#1}}% + \iffieldundef{#2}{}{\mbox{-}}}% + \iffieldundef{#2} + {} + {\mkmonthzeros{\thefield{#2}}% + \iffieldundef{#1}{}{\mbox{-}}}% + \iffieldbibstring{#3} + {\bibstring{\thefield{#3}}} + \stripzeros{\thefield{#3}}}% + \savecommand\mkdaterangeterse + \protected\def\mkdaterangeterse{% + \BibliographyWarning{% + Date format 'terse' not applicable to\MessageBreak + Spanish dates. Using format 'short' instead}% + \mkdaterangefull{short}}% + \savecommand\mkbibordedition + \savecommand\mkbibordseries + \def\mkbibordedition{\mkbibfemord}% + \def\mkbibordseries{\mkbibfemord}% + \expandafter\protected\expandafter\def\csname mkbibtime24h\endcsname#1#2#3#4{% + \iffieldundef{#1}{} + {\printtext{\mktimezeros{\thefield{#1}}}\setunit{\bibtimesep}}% + \iffieldundef{#2}{} + {\printtext{\mktimezeros{\thefield{#2}}}\setunit{\bibtimesep}}% + \iffieldundef{#3}{} + {\printtext{\mktimezeros{\thefield{#3}}}}% + \setunit{}% + \iffieldundef{#4}{} + {\bibtimezonesep + \mkbibtimezone{\thefield{#4}}}}% + \expandafter\protected\expandafter\def\csname mkbibtime12h\endcsname#1#2#3#4{% + \stripzeros{\mktimehh{\thefield{#1}}}\bibtimesep + \forcezerosmdt{\thefield{#2}}% + \iffieldundef{#3}{} + {\bibtimesep + \forcezerosmdt{\thefield{#3}}}% + \space + \ifnumless{\thefield{#1}}{12} + {\bibstring{am}} + {\bibstring{pm}}% + \iffieldundef{#4}{} + {\space\bibtimezonesep + \parentext{\mkbibtimezone{\thefield{#4}}}}}% + \protected\def\mkbibseasondateshort#1#2{% + \mkbibseason{\thefield{#2}}% + \iffieldundef{#1}{}{\space}% + \dateeraprintpre{#1}\mkyearzeros{\thefield{#1}}}% + \protected\def\mkbibseasondatelong#1#2{% + \mkbibseason{\thefield{#2}}% + \iffieldundef{#1}{}{\space}% + \dateeraprintpre{#1}\mkyearzeros{\thefield{#1}}}% +} + +\UndeclareBibliographyExtras{% + \restorecommand\mkdaterangeterse + \restorecommand\lbx@finalnamedelim + \restorecommand\lbx@finallistdelim + \restorecommand\mkbibordedition + \restorecommand\mkbibordseries +} + +\DeclareBibliographyStrings{% + bibliography = {{Bibliografia}{Bibliografia}},% + references = {{Erreferentziak}{Erreferentziak}},% + shorthands = {{Laburduren zerrenda}{Laburdurak}},% + editor = {{editorea}{ed\adddot}},% + editors = {{editoreak}{edk\adddot}},% + compiler = {{biltzailea}{biltz\adddot}},% + compilers = {{biltzaileak}{biltzk\adddot}},% + redactor = {{erredaktorea}{err\adddot}},% + redactors = {{erredakotreak}{errk\adddot}},% + reviser = {{orraztailea}{orr\adddot}},% + revisers = {{orraztaileak}{orrk\adddot}},% + founder = {{sortzailea}{sor\adddot}},% + founders = {{sortzaileak}{sork\adddot}},% + continuator = {{jarraitzailea}{jarr\adddot}},% + continuators = {{jarraitzaileak}{jarrk\adddot}},% + collaborator = {{kolaboratzailea}{kolab\adddot}},% + collaborators = {{kolaboratzaileak}{kolabk\adddot}},% + translator = {{itzulpena}{itz\adddot}},% + translators = {{itzulpena}{itz\adddot}},% + commentator = {{iruzkingilea}{irzgl\adddot}},% + commentators = {{iruzkingileak}{irzglk\adddot}},% + annotator = {{ohargilea}{ohr\adddot}},% + annotators = {{ohargileak}{ohrk\adddot}},% + commentary = {{iruzkina}{ir\adddot}},% + annotations = {{oharrak}{ohk\adddot}},% + introduction = {{sarrera}{sar\adddot}},% + foreword = {{hitzaurrea}{hitzaur\adddot}},% + afterword = {{hitzatzea}{hitzatz\adddot}},% + editortr = {{edizioa eta \lbx@sfromlang\ itzulpena}{ed\adddotspace eta \lbx@sfromlang\ itz\adddot}},% + editorstr = {{edizioa eta \lbx@sfromlang\ itzulpena}{ed\adddotspace eta \lbx@sfromlang\ itz\adddot}},% + editorco = {{edizioa eta iruzkinak}{ed\adddotspace eta irk\adddot}},% + editorsco = {{edizioa eta iruzkinak}{ed\adddotspace eta irk\adddot}},% + editoran = {{edizioa eta oharrak}{ed\adddotspace eta ohk\adddot}},% + editorsan = {{edizioa eta oharrak}{ed\adddotspace eta ohk\adddot}},% + editorin = {{edizioa eta sarrera}{ed\adddotspace eta sar\adddot}},% + editorsin = {{edizioa eta sarrera}{ed\adddotspace eta sar\adddot}},% + editorfo = {{edizioa eta hitzaurrea}{ed\adddotspace eta hitzaur\adddot}},% + editorsfo = {{edizioa eta hitzaurrea}{ed\adddotspace eta hitzaur\adddot}},% + editoraf = {{edizioa eta hitzatzea}{ed\adddotspace eta hitzatz\adddot}},% + editorsaf = {{edizioa eta hitzatzea}{ed\adddotspace eta hitzatz\adddot}},% + editortrco = {{edizioa, \lbx@sfromlang\ itzulpena eta iruzkinak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta irzk\adddot}},% + editorstrco = {{edizioa, \lbx@sfromlang\ itzulpena eta iruzkinak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta irzk\adddot}},% + editortran = {{edizioa, \lbx@sfromlang\ itzulpena eta oharrak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta ohk\adddot}},% + editorstran = {{edizioa, \lbx@sfromlang\ itzulpena eta oharrak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta ohk\adddot}},% + editortrin = {{edizioa, \lbx@sfromlang\ itzulpena eta sarrera}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta sar\adddot}},% + editorstrin = {{edizioa, \lbx@sfromlang\ itzulpena eta sarrera}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta sar\adddot}},% + editortrfo = {{edizioa, \lbx@sfromlang\ itzulpena eta hitzaurrea}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta hitzaur\adddot}},% + editorstrfo = {{edizioak, \lbx@sfromlang\ itzulpenak eta hitzaurrea}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddotspace eta hitzaur\adddot}},% + editortraf = {{edizioa, \lbx@sfromlang\ itzulpena eta hitzatzea}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddotspace eta hitzatz\adddot}},% + editorstraf = {{edizioak, \lbx@sfromlang\ itzulpenak eta hitzatzea}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddotspace eta hitzatz\adddot}},% + editorcoin = {{edizioa, iruzkinak eta sarrera}{ed.,\addabbrvspace irzk\adddotspace eta sar\adddot}},% + editorscoin = {{edizioak, iruzkinak eta sarrera}{edk.,\addabbrvspace irzk\adddotspace eta sar\adddot}},% + editorcofo = {{edizioa, iruzkinak eta hitzaurrea}{ed.,\addabbrvspace irzk\adddotspace eta hitzaur\adddot}},% + editorscofo = {{edizioak, iruzkinak eta hitzaurrea}{edk.,\addabbrvspace irzk\adddotspace eta hitzaur\adddot}},% + editorcoaf = {{edizioa, iruzkinak eta hitzatzea}{ed.,\addabbrvspace irzk\adddotspace eta hitzatz\adddot}},% + editorscoaf = {{edizioak, iruzkinak eta hitzatzea}{edk.,\addabbrvspace irzk\adddotspace eta hitzatz\adddot}},% + editoranin = {{edizioa, oharrak eta sarrera}{ed.,\addabbrvspace ohk\adddotspace eta sar\adddot}},% + editorsanin = {{edizioak, oharrak eta sarrera}{edk.,\addabbrvspace ohk\adddotspace eta sar\adddot}},% + editoranfo = {{edizioa, oharrak eta hitzaurrea}{ed.,\addabbrvspace ohk\adddotspace eta hitzatz\adddot}},% + editorsanfo = {{edizioak, oharrak eta hitzaurrea}{edk.,\addabbrvspace ohk\adddotspace eta hitzatz\adddot}},% + editoranaf = {{edizioa, oharrak eta hitzatzea}{ed.,\addabbrvspace ohk\adddotspace eta hitzatz\adddot}},% + editorsanaf = {{edizioak, oharrak eta hitzatzea}{edk.,\addabbrvspace ohk\adddotspace eta hitzatz\adddot}},% + editortrcoin = {{edizioa, \lbx@sfromlang\ itzulpena, iruzkinak eta sarrera}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace irzk\adddotspace eta sar\adddot}},% + editorstrcoin = {{edizioak, \lbx@sfromlang\ itzulpenak, iruzkinak eta sarrera}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace irzk\adddotspace eta sar\adddot}},% + editortrcofo = {{edizioa, \lbx@sfromlang\ itzulpena, iruzkinak eta hitzaurrea}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace irzk\adddotspace eta hitzaur\adddot}},% + editorstrcofo = {{edizioak, \lbx@sfromlang\ itzulpenak, iruzkinak eta hitzaurrea}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace irzk\adddotspace eta hitzaur\adddot}},% + editortrcoaf = {{edizioa, \lbx@sfromlang\ itzulpena, iruzkinak eta hitzatzea}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace irzk\adddotspace eta hitzatz\adddot}},% + editorstrcoaf = {{edizioak, \lbx@sfromlang\ itzulpenak, iruzkinak eta hitzatzea}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace irzk\adddotspace eta hitzatz\adddot}},% + editortranin = {{edizioa, \lbx@sfromlang\ itzulpena, sarrera eta oharrak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace sar\adddotspace eta ohk\adddot}},% + editorstranin = {{edizioak, \lbx@sfromlang\ itzulpenak, sarrera eta oharrak}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace sar\adddotspace eta ohk\adddot}},% + editortranfo = {{edizioa, \lbx@sfromlang\ itzulpena, hitzaurrea eta oharrak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace hitzaur\adddotspace eta ohk\adddot}},% + editorstranfo = {{edizioak, \lbx@sfromlang\ itzulpenak, hitzaurrea eta oharrak}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace hitzaur\adddotspace eta ohk\adddot}},% + editortranaf = {{edizioa, \lbx@sfromlang\ itzulpena, hitzatzea eta oharrak}{ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot,\addabbrvspace hitzatz\adddotspace eta ohk\adddot}},% + editorstranaf = {{edizioak, \lbx@sfromlang\ itzulpenak, hitzatzea eta oharrak}{edk.,\addabbrvspace \lbx@sfromlang\ itzk\adddot,\addabbrvspace hitzatz\adddotspace eta ohk\adddot}},% + translatorco = {{\lbx@sfromlang\ itzulpena eta iruzkinak}{\lbx@sfromlang\ itz\adddot\ eta irzk\adddot}},% + translatorsco = {{\lbx@sfromlang\ itzulpenak eta iruzkinak}{\lbx@sfromlang\ itzk\adddot\ eta irzk\adddot}},% + translatoran = {{\lbx@sfromlang\ itzulpena eta oharrak}{\lbx@sfromlang\ itz\adddot\ eta ohk\adddot}},% + translatorsan = {{\lbx@sfromlang\ itzulpenak eta oharrak}{\lbx@sfromlang\ itzk\adddot\ eta ohks\adddot}},% + translatorin = {{\lbx@sfromlang\ itzulpena eta sarrera}{\lbx@sfromlang\ itz\adddot\ eta sar\adddot}},% + translatorsin = {{\lbx@sfromlang\ itzulpenak eta sarrera}{\lbx@sfromlang\ itzk\adddot\ eta sar\adddot}},% + translatorfo = {{\lbx@sfromlang\ itzulpena eta hitzaurrea}{\lbx@sfromlang\ itz\adddot\ eta hitzaur\adddot}},% + translatorsfo = {{\lbx@sfromlang\ itzulpenak eta hitzaurrea}{\lbx@sfromlang\ itzk\adddot\ eta hitzaur\adddot}},% + translatoraf = {{\lbx@sfromlang\ itzulpena eta hitzatzea}{\lbx@sfromlang\ itz\adddot\ eta hitzatz\adddot}},% + translatorsaf = {{\lbx@sfromlang\ itzulpenak eta hitzatzea}{\lbx@sfromlang\ itzk\adddot\ eta hitzatz\adddot}},% + translatorcoin = {{\lbx@sfromlang\ itzulpena, sarrera eta iruzkinak}{\lbx@sfromlang\ itz\adddot, sar\adddotspace eta irzk\adddot}},% + translatorscoin = {{\lbx@sfromlang\ itzulpenak, sarrera eta iruzkinak}{\lbx@sfromlang\ itzk\adddot, sar\adddotspace eta irzk\adddot}},% + translatorcofo = {{\lbx@sfromlang\ itzulpena, hitzaurrea eta iruzkinak}{\lbx@sfromlang\ itz\adddot, hitzaur\adddotspace eta irzk\adddot}},% + translatorscofo = {{\lbx@sfromlang\ itzulpenak, hitzaurrea eta iruzkinak}{\lbx@sfromlang\ itzk\adddot, hitzaur\adddotspace eta irzk\adddot}},% + translatorcoaf = {{\lbx@sfromlang\ itzulpena, hitzatzea eta iruzkinak}{\lbx@sfromlang\ itz\adddot, hitzatz\adddotspace eta irzk\adddot}},% + translatorscoaf = {{\lbx@sfromlang\ itzulpenak, hitzatzea eta iruzkinak}{\lbx@sfromlang\ itzk\adddot, hitzatz\adddotspace eta irzk\adddot}},% + translatoranin = {{\lbx@sfromlang\ itzulpena, sarrera eta oharrak}{\lbx@sfromlang\ itz\adddot, sar\adddotspace eta ohk\adddot}},% + translatorsanin = {{\lbx@sfromlang\ itzulpenak, sarrera eta oharrak}{\lbx@sfromlang\ itzk\adddot, sar\adddotspace eta ohk\adddot}},% + translatoranfo = {{\lbx@sfromlang\ itzulpena, hitzaurrea eta oharrak}{\lbx@sfromlang\ itz\adddot, hitzaur\adddotspace eta ohk\adddot}},% + translatorsanfo = {{\lbx@sfromlang\ itzulpenak, hitzaurrea eta oharrak}{\lbx@sfromlang\ itzk\adddot, hitzaur\adddotspace eta ohk\adddot}},% + translatoranaf = {{\lbx@sfromlang\ itzulpena, hitzatzea eta oharrak}{\lbx@sfromlang\ itz\adddot, hitzatz\adddotspace eta ohk\adddot}},% + translatorsanaf = {{\lbx@sfromlang\ itzulpenak, hitzatzea eta oharrak}{\lbx@sfromlang\ itzk\adddot, hitzatz\adddotspace eta ohk\adddot}},% + organizer = {{antolatzailea(k)}{antltz(k)\adddot}},% + organizers = {{antolatzailea(k)}{antltz(k)\adddot}},% + byorganizer = {{antolatzailea(k)}{antltz(k)\adddot}},% + byauthor = {{egilea(k)}{eg(k)}},% + byeditor = {{editorea(k)}{ed(k)}},% + bycompiler = {{biltzailea(k)}{biltz(k)}},% + byredactor = {{erredaktorea(k)}{err(k)}},% + byreviser = {{orraztailea(k)}{orrz(k)}},% + byreviewer = {{berrikustzailea(k)}{berr(k)}},% + byfounder = {{sortzailea(k)}{sortz(k)}},% + bycontinuator = {{jarraitzailea(k)}{jarr(k)}},% + bycollaborator = {{kolaboratzailea(k)}{kolab(k)}},% + bytranslator = {{\lbx@lfromlang\ itzulpena}{\lbx@sfromlang\ itz\adddot}},% + bycommentator = {{iruzkinak}{irzk\adddotspace}},% + byannotator = {{oharrak}{ohk\adddot}},% + withcommentator = {{iruzkinak}{irzk\adddot}},% + withannotator = {{oharrak}{ohk\adddot}},% + withintroduction = {{sarrera}{sar\adddot}},% + withforeword = {{hitzaurrea}{hitzaur\adddot}},% + withafterword = {{hitzatzea}{hitzatz\adddot}},% + byeditortr = {{edizioa eta \lbx@lfromlang\ itzulpena}% + {ed\adddotspace eta \lbx@sfromlang\ itz\adddot}},% + byeditorco = {{edizioa eta iruzkinak}% + {ed\adddotspace eta irzk\adddot}},% + byeditoran = {{edizioa eta oharrak}% + {ed\adddotspace eta ohk\adddot}},% + byeditorin = {{edizioa eta sarrera}% + {ed\adddotspace eta sar\adddot}},% + byeditorfo = {{edizioa eta hitzaurrea}% + {ed\adddotspace eta hitzaur\adddot}},% + byeditoraf = {{edizioa eta hitzatzea}% + {ed\adddotspace eta hitzatz\adddot}},% + byeditortrco = {{edizioa, \lbx@lfromlang\ itzulpena eta iruzkinak}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot\ eta irzk\adddot}},% + byeditortran = {{edizioa, \lbx@lfromlang\ itzulpena eta oharrak}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot\ eta ohk\adddot}},% + byeditortrin = {{edizioa, \lbx@lfromlang\ itzulpena eta sarrera}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot\ eta sar\adddot}},% + byeditortrfo = {{edizioa, \lbx@lfromlang\ itzulpena eta hitzaurrea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot\ eta hitzaur\adddot}},% + byeditortraf = {{edizioa, \lbx@lfromlang\ itzulpena eta hitzatzea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot\ eta hitzatz\adddot}},% + byeditorcoin = {{edizioa, iruzkinak eta sarrera}% + {ed.,\addabbrvspace irzk\adddotspace eta sar\adddot}},% + byeditorcofo = {{edizioa, iruzkinak eta hitzaurrea}% + {ed.,\addabbrvspace irzk\adddotspace eta hitzaur\adddot}},% + byeditorcoaf = {{edizioa, iruzkinak eta hitzatzea}% + {ed.,\addabbrvspace irzk\adddotspace eta hitzatz\adddot}},% + byeditoranin = {{edizioa, oharrak eta sarrera}% + {ed.,\addabbrvspace ohk\adddotspace eta sar\adddot}},% + byeditoranfo = {{edizioa, oharrak eta hitzaurrea}% + {ed.,\addabbrvspace ohk\adddotspace eta hitzaur\adddot}},% + byeditoranaf = {{edizioa, oharrak eta hitzatzea}% + {ed.,\addabbrvspace ohk\adddotspace eta hitzatz\adddot}},% + byeditortrcoin = {{edizioa, \lbx@lfromlang itzulpena, iruzkinak eta sarrera}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, irzk\adddotspace eta sar\adddot}},% + byeditortrcofo = {{edizioa, \lbx@lfromlang itzulpena, iruzkinak eta hitzaurrea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, irzk\adddotspace eta hitzaur\adddot}},% + byeditortrcoaf = {{edizioa, \lbx@lfromlang itzulpena, iruzkinak eta hitzatzea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, irzk\adddotspace eta hitzatz\adddot}},% + byeditortranin = {{edizioa, \lbx@lfromlang itzulpena, oharrak eta sarrera}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, ohk\adddotspace eta sar\adddot}},% + byeditortranfo = {{edizioa, \lbx@lfromlang itzulpena, oharrak eta hitzaurrea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, ohk\adddotspace eta hitzaur\adddot}},% + byeditortranaf = {{edizioa, \lbx@lfromlang itzulpena, oharrak eta hitzatzea}% + {ed.,\addabbrvspace \lbx@sfromlang\ itz\adddot, ohk\adddotspace eta hitzatz\adddot}},% + bytranslatorco = {{\lbx@lfromlang\ itzulpena eta iruzkinak}% + {\lbx@sfromlang\ itz\adddot\ eta irzk\adddot}},% + bytranslatoran = {{\lbx@lfromlang\ itzulpena eta oharrak}% + {\lbx@sfromlang\ itz\adddot\ eta ohk\adddot}},% + bytranslatorin = {{\lbx@lfromlang\ itzulpena eta sarrera}% + {\lbx@sfromlang\ itz\adddot\ eta sarod\adddot}},% + bytranslatorfo = {{\lbx@lfromlang\ itzulpena eta hitzaurrea}% + {\lbx@sfromlang\ itz\adddot\ eta hitzaur\adddot}},% + bytranslatoraf = {{\lbx@lfromlang\ itzulpena eta hitzatzea}% + {\lbx@sfromlang\ itz\adddot\ eta hitzatz\adddot}},% + bytranslatorcoin = {{\lbx@lfromlang itzulpena, iruzkinak eta sarrera}% + {\lbx@sfromlang itz\adddot, irzk\adddotspace eta sar\adddot}},% + bytranslatorcofo = {{\lbx@lfromlang itzulpena, iruzkinak eta hitzaurrea}% + {\lbx@sfromlang itz\adddot, irzk\adddotspace eta pr\'ol\adddot}},% + bytranslatorcoaf = {{\lbx@lfromlang itzulpena, iruzkinak eta hitzatzea}% + {\lbx@sfromlang itz\adddot, irzk\adddotspace eta hitzatz\adddot}},% + bytranslatoranin = {{\lbx@lfromlang itzulpena, oharrak eta sarrera}% + {\lbx@sfromlang itz\adddot, ohk\adddotspace eta sar\adddot}},% + bytranslatoranfo = {{\lbx@lfromlang itzulpena, oharrak eta hitzaurrea}% + {\lbx@sfromlang itz\adddot, ohk\adddotspace eta pr\'ol\adddot}},% + bytranslatoranaf = {{\lbx@lfromlang itzulpena, oharrak eta hitzatzea}% + {\lbx@sfromlang itz\adddot, ohk\adddotspace eta hitzatz\adddot}},% + and = {{eta}{eta}},% + andothers = {{et\adddotspace al\adddot}{et\adddotspace al\adddot}},% + andmore = {{et\adddotspace al\adddot}{et\adddotspace al\adddot}},% + volume = {{bolumena}{bol\adddot}},% + volumes = {{bolumeank}{bolk\adddot}},% + involumes = {{non}{non}},% + jourvol = {{bolumena}{bol\adddot}},% + jourser = {{serie-zenbaki}{ser-zb\adddot}},% + book = {{liburua}{liburua}},% + part = {{atala}{atala}},% + issue = {{zenbakia}{zk\adddot}},% + newseries = {{serie-zenbaki berria}{ser-zb ber\adddot}},% + oldseries = {{serie-zenbaki zaharra}{ser-zb zah\adddot}},% + edition = {{edizioa}{ed\adddot}},% + reprint = {{berrinprimatzea}{berrinp\adddot}},% + reprintof = {{berrinprimatzea}{berrinp\adddot}},% + reprintas = {{berrinprimitua}{berrinp\adddot}},% + reprintfrom = {{berrinprimitua}{berrinp\adddot}},% + reviewof = {{erreseina}{erres\adddot}},% + translationof = {{itzulpena}{itz\adddot}},% + translationas = {{zein hizkuntzara itzulia}{zein hizk\adddot -ra itz\adddot}},% + translationfrom = {{zein hizkuntzatik itzulia}{zein hizk\adddotspace itz\adddot}},% + origpubas = {{originalki argitaratua}{orig\adddotspace argit\adddotspace}},% + origpubin = {{originalki argitaratua}{orig\adddot argit\adddot}},% + astitle = {{izenburua}{izenb\adddot}},% + bypublisher = {{argitaletxea}{argit\adddot}},% + nodate = {{datarik gabe}{dat\adddot gabe}},% + page = {{orria}{orr\adddot}},% + pages = {{orriak}{orrk\adddot}},% + column = {{zutabea}{ztb\adddot}},% + columns = {{zutabeak}{ztbk\adddot}},% + line = {{lerroa}{lerr\adddot}},% + lines = {{lerroak}{lerrk\adddot}},% + verse = {{lerroa}{lerr\adddot}},% + verses = {{lerroak}{lerrk\adddot}},% + section = {{atala}{at\adddot}},% + sections = {{atalak}{atk\adddot}},% + paragraph = {{parrafoa}{parr\adddot}},% + paragraphs = {{parrafoak}{parrk\adddot}},% + pagetotal = {{orria}{orr\adddot}},% + pagetotals = {{orriak}{orrk\adddot}},% + columntotal = {{zutabea}{ztb\adddot}},% + columntotals = {{zutabeak}{ztbk\adddot}},% + linetotal = {{lerroa}{lerr\adddot}},% + linetotals = {{lerroak}{lerrk\adddot}},% + versetotal = {{verso}{v\adddot}}, + versetotals = {{versos}{vv\adddot}}, + sectiontotal = {{atala}{at\adddot}},% + sectiontotals = {{atalak}{atk\adddot}},% + paragraphtotal = {{parrafoa}{parr\adddot}},% + paragraphtotals = {{parrafoak}{parrk\adddot}},% + in = {{non}{non}},% + inseries = {{non}{non}},% + ofseries = {{nongo}{nongo}},% + number = {{zenbakia}{zb\adddot}},% + chapter = {{kapitulua}{kap\adddot}},% + bathesis = {{Lizentziatura tesia}{Liz\adddotspace tesia}},% + mathesis = {{Maisutza tesia}{Mais\adddotspace tesia}},% + phdthesis = {{Tesi doktorala}{Tesi dokt\adddot}},% + candthesis = {{Doktoretzarako hautagaitza tesia}{Dokt\adddotspace haut\adddotspace tesia}},% + resreport = {{ikerketa txostena}{ik\adddotspace txos\adddot}},% + techreport = {{txosten teknikoa}{txos\adddotspace tek\adddot}},% + software = {{programa}{prog\adddot}},% + datacd = {{datu CD-a}{datu CD-a}},% + audiocd = {{audio CD-a}{audio CD-a}},% + version = {{bertsioa}{ber\adddot}},% + url = {{esteka}{esteka}},% + urlfrom = {{noiztik erabilgarri}{erabilg\adddot}},% + urlseen = {{azkenekoz ikusia}{azkenekoz ikusia}},% + inpreparation = {{prestaketa prozesuan}{prest\adddot proz\adddot}},% + submitted = {{bidalia}{bidalia}},% + forthcoming = {{laster}{laster}},% + inpress = {{inprentan}{inprentan}},% + prepublished = {{aurrez argitaratua}{aur\adddot argit\adddot}},% + citedas = {{aurrerantzean aipatua}{aur\adddot aip\adddot}},% + thiscite = {{bereziki}{berez\adddot}},% + seenote = {{ikus oharra}{ik\adddot oh\adddot}},% + quotedin = {{aipatua}{aip\adddot}},% + idem = {{idem}{id\adddot}},% + idemsf = {{idem}{id\adddot}},% + idemsm = {{idem}{id\adddot}},% + idemsn = {{idem}{id\adddot}},% + idempf = {{idem}{id\adddot}},% + idempm = {{idem}{id\adddot}},% + idempn = {{idem}{id\adddot}},% + idempp = {{idem}{id\adddot}},% + ibidem = {{ibidem}{ibid\adddot}},% + opcit = {{op\adddotspace cit\adddot}{o\adddot cit\adddot}},% + loccit = {{loc\adddotspace cit\adddot}{loc\adddot cit\adddot}},% + confer = {{cf\adddot}{cf\adddot}},% + sequens = {{hurr\adddot}{hurr\adddot}},% + sequentes = {{hurrk\adddot}{hurrk\adddot}},% + passim = {{passim}{passim}},% + see = {{ikus}{ik\adddot}},% + seealso = {{ikus ere}{ik\adddotspace ere}},% + backrefpage = {{ikus orria}{ik\adddotspace orr\adddot}},% + backrefpages = {{ikus orriak}{ik\adddotspace orrk\adddot}},% + january = {{urtarrila}{urt\adddot}},% + february = {{otsaila}{ots\adddot}},% + march = {{martxoa}{mar\adddot}},% + april = {{apirila}{ap\adddot}},% + may = {{maiatza}{mai\adddot}},% + june = {{ekaina}{ek\adddot}},% + july = {{uztaila}{uz\adddot}},% + august = {{abuztua}{abu\adddot}},% + september = {{iraila}{ir\adddot}},% + october = {{urria}{urr\adddot}},% + november = {{azaroa}{az\adddot}},% + december = {{abendua}{abe\adddot}},% + langamerican = {{ingleles amerikarra}{ingeles amerikarra}},% + langbrazilian = {{portugesa}{portugesa}},% + langbulgarian = {{bulgariera}{bulgariera}},% + langcatalan = {{katalana}{katalana}},% + langcroatian = {{kroaziera}{kroaziera}},% + langczech = {{txekiera}{txekiera}},% + langdanish = {{daniera}{daniera}},% + langdutch = {{nederlandera}{nederlandera}},% + langenglish = {{ingelesa}{ingelesa}},% + langestonian = {{estoniera}{estoniera}},% + langfinnish = {{finlandiera}{finlandiera}},% + langfrench = {{frantsesa}{frantsesa}},% + langgalician = {{galiziera}{galiziera}},% + langgerman = {{alemana}{alemana}},% + langgreek = {{greziera}{greziera}},% + langhungarian = {{hungariera}{hungariera}},% + langitalian = {{italiera}{italiera}},% + langjapanese = {{japoniera}{japoniera}},% + langlatin = {{latina}{latina}},% + langlatvian = {{lituaniera}{lituaniera}},% + langnorwegian = {{norvegiera}{norvegiera}},% + langpolish = {{poloniera}{poloniera}},% + langportuguese = {{portugesa}{portugesa}},% + langrussian = {{errusiera}{errusiera}},% + langslovak = {{eslovakiera}{eslovakiera}},% + langslovene = {{esloveniera}{esloveniera}},% + langspanish = {{gaztelera}{gaztelera}},% + langswedish = {{suediera}{suediera}},% + langukrainian = {{ukrainera}{ukrainera}},% + fromamerican = {{ingeles amerikarretik}{ingeles amerikarretik}},% + frombrazilian = {{portugesetik}{portugesetik}},% + frombulgarian = {{bulgarieratik}{bulgarieratik}},% + fromcatalan = {{katalanetik}{katalanetik}},% + fromcroatian = {{kroazieratik}{kroazieratik}},% + fromczech = {{txekieratik}{txekieratik}},% + fromdanish = {{danieratik}{danieratik}},% + fromdutch = {{nederlanderatik}{nederlanderatik}},% + fromenglish = {{ingelesetik}{ingelesetik}},% + fromestonian = {{estonieratik}{estonieratik}},% + fromfinnish = {{finlandieratik}{finlandieratik}},% + fromfrench = {{frantsesetik}{frantsesetik}},% + fromgalician = {{galizieratik}{galizieratik}},% + fromgerman = {{alemanetik}{alemanetik}},% + fromgreek = {{grezieratik}{grezieratik}},% + fromhungarian = {{hungarieratik}{hungarieratik}},% + fromitalian = {{italieratik}{italieratik}},% + fromjapanese = {{japonieratik}{japonieratik}},% + fromlatin = {{latinetik}{latinetik}},% + fromlatvian = {{lituanieratik}{lituanieratik}},% + fromnorwegian = {{norvegieratik}{norvegieratik}},% + frompolish = {{polonieratik}{polonieratik}},% + fromportuguese = {{portugesetik}{portugesetik}},% + fromrussian = {{errusieratik}{errusieratik}},% + fromslovak = {{eslovakieratik}{eslovakieratik}},% + fromslovene = {{eslovenieratik}{eslovenieratik}},% + fromspanish = {{gazteleratik}{gazteleratik}},% + fromswedish = {{suedieratik}{suedieratik}},% + fromukrainian = {{ukraineratik}{ukraineratik}},% + countryde = {{Alemania}{DE}},% + countryeu = {{Europar Batasuna}{EU}},% + countryep = {{Europar Batasuna}{EP}},% + countryfr = {{Frantzia}{FR}},% + countryuk = {{Britainia Handia}{GB}},% + countryus = {{Ameriketako Estatu Batuak}{US}},% + patent = {{patentea}{pat\adddot}},% + patentde = {{patente alemana}{pat\adddotspace alemana}},% + patenteu = {{patente europarra}{pat\adddotspace europarra}},% + patentfr = {{patente frantsesa}{pat\adddotspace frantsesa}},% + patentuk = {{patente britainiarra}{pat\adddotspace britainiarra}},% + patentus = {{patente estatubatuarra}{pat\adddotspace estatubatuarra}},% + patreq = {{patente eskakizuna}{pat\adddotspace esk\adddot}},% + patreqde = {{patente alemanaaren eskakizuna}{pat\adddotspace alem\adddotspace esk\adddot}},% + patreqeu = {{patente europarraren eskakizuna}{pat\adddotspace europ\adddotspace esk\adddot}},% + patreqfr = {{patente frantsesaren eskakizuna}{pat\adddotspace frants\adddotspace esk\adddot}},% + patrequk = {{patente britainiarraren eskakizuna}{pat\adddotspace brit\adddotspace esk\adddot}},% + patrequs = {{patente estatubatuarraren eskakizuna}{pat\adddotspace estat\adddotspace esk\adddot}},% + file = {{fitxategia}{fitxategia}},% + library = {{biblioteka}{bibl\adddot}},% + abstract = {{laburpena}{laburpena}},% + annotation = {{oharra}{oh\adddot}},% + commonera = {{oraingo aroa}{o\adddotspace a\adddot}},% + beforecommonera = {{oraingo aroaren aurretik}{o\adddotspace a\adddotspace a\adddot}},% + annodomini = {{Kristo ondoren}{K\adddotspace o\adddot}},% + beforechrist = {{Kristo aurretik}{K\adddotspace a\adddot}},% + circa = {{circa}{ca\adddot}},% + spring = {{udaberria}{udab\adddot}},% + summer = {{uda}{uda}},% + autumn = {{udazkena}{udaz\adddot}},% + winter = {{negua}{neg\adddot}},% + am = {{a\adddotspace m\adddot}{a\adddot m\adddot}},% + pm = {{p\adddotspace m\adddot}{p\adddot m\adddot}},% +} + +\endinput diff --git a/macros/latex/contrib/biblatex/latex/lbx/catalan.lbx b/macros/latex/contrib/biblatex/latex/lbx/catalan.lbx index 4f1878ac4d..abf7f8522c 100644 --- a/macros/latex/contrib/biblatex/latex/lbx/catalan.lbx +++ b/macros/latex/contrib/biblatex/latex/lbx/catalan.lbx @@ -274,90 +274,90 @@ organizers = {{organitzadors}{org\adddot}}, byorganizer = {{organitzat per}{org\adddotspace per}}, byauthor = {{per}{per}}, - byeditor = {{edici\'o a cura \smartof}{ed\adddotspace\smartof}}, - bycompiler = {{compilaci\'o a cura \smartof}{comp\adddotspace\smartof}}, - byredactor = {{redacci\'o a cura \smartof}{red\adddotspace\smartof}}, - byreviser = {{revisi\'o a cura \smartof}{rev\adddotspace\smartof}}, - byreviewer = {{ressenya a cura \smartof}{ress\adddotspace\smartof}}, + byeditor = {{edici\'o a cura\smartof}{ed\adddot\smartof}}, + bycompiler = {{compilaci\'o a cura\smartof}{comp\adddot\smartof}}, + byredactor = {{redacci\'o a cura\smartof}{red\adddot\smartof}}, + byreviser = {{revisi\'o a cura\smartof}{rev\adddot\smartof}}, + byreviewer = {{ressenya a cura\smartof}{ress\adddot\smartof}}, byfounder = {{fundat per}{fund\adddotspace per}}, bycontinuator = {{continuat per}{cont\adddotspace per}}, - bycollaborator = {{amb la co\l.laboraci\'o \smartof}{amb la co\l.l\adddotspace\smartof}}, - bytranslator = {{traducci\'o \lbx@fromlang\ a cura \smartof}{trad\adddotspace\lbx@fromlang\ \smartof}}, - bycommentator = {{comentari a cura \smartof}{com\adddotspace\smartof}}, - byannotator = {{notes a cura \smartof}{n\adddotspace\smartof}}, - withcommentator = {{amb un comentari a cura \smartof}{amb un com\adddotspace\smartof}}, - withannotator = {{amb notes a cura \smartof}{amb n\adddotspace\smartof}}, - withintroduction = {{amb una introducci\'o a cura \smartof}{amb una intr\adddotspace\smartof}}, - withforeword = {{amb un pr\`oleg a cura \smartof}{amb un pr\`ol\adddotspace\smartof}}, - withafterword = {{amb un ep\'{\i}leg a cura \smartof}{amb un ep\adddotspace\smartof}}, - byeditortr = {{edici\'o i traducci\'o \lbx@fromlang\ a cura \smartof}% - {ed\adddotspace i trad\adddotspace\lbx@fromlang\ \smartof}}, - byeditorco = {{edici\'o i comentari a cura \smartof}% - {ed\adddotspace i com\adddotspace\smartof}}, - byeditoran = {{edici\'o i notes a cura \smartof}% - {ed\adddotspace i n\adddotspace\smartof}}, - byeditorin = {{edici\'o i introducci\'o a cura \smartof}% - {ed\adddotspace i intr\adddotspace\smartof}}, - byeditorfo = {{edici\'o i pr\`oleg a cura \smartof}% - {ed\adddotspace i pr\`ol\adddotspace\smartof}}, - byeditoraf = {{edici\'o i ep\'{\i}leg a cura \smartof}% - {ed\adddotspace i ep\adddotspace\smartof}}, - byeditortrco = {{edici\'o, traducci\'o \lbx@fromlang\ i comentari a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i com\adddotspace\smartof}}, - byeditortran = {{edici\'o, traducci\'o \lbx@fromlang\ i notes a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i n\adddotspace\smartof}}, - byeditortrin = {{edici\'o, traducci\'o \lbx@fromlang\ i introducci\'o a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i intr\adddotspace\smartof}}, - byeditortrfo = {{edici\'o, traducci\'o \lbx@fromlang\ i pr\`oleg a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i pr\`ol\adddotspace\smartof}}, - byeditortraf = {{edici\'o, traducci\'o \lbx@fromlang\ i ep\'{\i}leg a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i ep\adddotspace\smartof}}, - byeditorcoin = {{edici\'o, comentari i introducci\'o a cura \smartof} - {ed.,\addabbrvspace com\adddotspace i intr\adddotspace\smartof}}, - byeditorcofo = {{edici\'o, comentari i pr\`oleg a cura \smartof} - {ed.,\addabbrvspace com\adddotspace i pr\`ol\adddotspace\smartof}}, - byeditorcoaf = {{edici\'o, comentari i ep\'{\i}leg a cura \smartof}% - {ed.,\addabbrvspace com\adddotspace i ep\adddotspace\smartof}}, - byeditoranin = {{edici\'o, notes i introducci\'o a cura \smartof}% - {ed.,\addabbrvspace n\adddotspace i intr\adddotspace\smartof}}, - byeditoranfo = {{edici\'o, notes i pr\`oleg a cura \smartof}% - {ed.,\addabbrvspace n\adddotspace i pr\`ol\adddotspace\smartof}}, - byeditoranaf = {{edici\'o, notes i ep\'{\i}leg a cura \smartof}% - {ed.,\addabbrvspace n\adddotspace i ep\adddotspace\smartof}}, - byeditortrcoin = {{edici\'o, traducci\'o \lbx@fromlang, comentari i introducci\'o a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace \lbx@fromlang, com\adddotspace i intr\adddotspace\smartof}}, - byeditortrcofo = {{edici\'o, traducci\'o \lbx@fromlang, comentari i pr\`oleg a cura \smartof}% - {ed.,\addabbrvspace trad\adddotspace \lbx@fromlang, com\adddotspace i pr\`ol\adddotspace\smartof}}, - byeditortrcoaf = {{edici\'o, traducci\'o \lbx@fromlang, comentari i ep\'{\i}leg a cura \smartof}% - {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, com\adddot\ i ep\adddot\ \smartof}}, - byeditortranin = {{edici\'o, traducci\'o \lbx@fromlang, notes i introducci\'o a cura \smartof}% - {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i intr\adddot\ \smartof}}, - byeditortranfo = {{edici\'o, traducci\'o \lbx@fromlang, notes i pr\`oleg a cura \smartof}% - {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i pr\`ol\adddot\ \smartof}}, - byeditortranaf = {{edici\'o, traducci\'o \lbx@fromlang, notes i ep\'{\i}leg a cura \smartof}% - {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i ep\adddot\ \smartof}}, - bytranslatorco = {{traducci\'o \lbx@fromlang\ i comentari a cura \smartof}% - {trad\adddot\ \lbx@fromlang\ i com\adddot\ \smartof}}, - bytranslatoran = {{traducci\'o \lbx@fromlang\ i notes a cura \smartof}% - {trad\adddot\ \lbx@fromlang\ i n\adddot\ \smartof}}, - bytranslatorin = {{traducci\'o \lbx@fromlang\ i introducci\'o a cura \smartof}% - {trad\adddot\ \lbx@fromlang\ i intr\adddot\ \smartof}}, - bytranslatorfo = {{traducci\'o \lbx@fromlang\ i pr\`oleg a cura \smartof}% - {trad\adddot\ \lbx@fromlang\ i pr\`ol\adddot\ \smartof}}, - bytranslatoraf = {{traducci\'o \lbx@fromlang\ i ep\'{\i}leg a cura \smartof}% - {trad\adddot\ \lbx@fromlang\ i ep\adddot\ \smartof}}, - bytranslatorcoin = {{traducci\'o \lbx@fromlang, comentari i introducci\'o a cura \smartof}% - {trad\adddot\ \lbx@fromlang, com\adddot\ i intr\adddot\ \smartof}}, - bytranslatorcofo = {{traducci\'o \lbx@fromlang, comentari i pr\`oleg a cura \smartof}% - {trad\adddot\ \lbx@fromlang, com\adddot\ i pr\`ol\adddot\ \smartof}}, - bytranslatorcoaf = {{traducci\'o \lbx@fromlang, comentari i ep\'{\i}leg a cura \smartof}% - {trad\adddot\ \lbx@fromlang, com\adddot\ i ep\adddot\ \smartof}}, - bytranslatoranin = {{traducci\'o \lbx@fromlang, notes i introducci\'o a cura \smartof}% - {trad\adddot\ \lbx@fromlang, n\adddot\ i intr\adddot\ \smartof}}, - bytranslatoranfo = {{traducci\'o \lbx@fromlang, notes i pr\`oleg a cura \smartof}% - {trad\adddot\ \lbx@fromlang, n\adddot\ i pr\`ol\adddot\ \smartof}}, - bytranslatoranaf = {{traducci\'o \lbx@fromlang, notes i ep\'{\i}leg a cura \smartof}% - {trad\adddot\ \lbx@fromlang, n\adddot\ i ep\adddot\ \smartof}}, + bycollaborator = {{amb la co\l.laboraci\'o\smartof}{amb la co\l.l\adddot\smartof}}, + bytranslator = {{traducci\'o \lbx@fromlang\ a cura\smartof}{trad\adddotspace\lbx@fromlang\smartof}}, + bycommentator = {{comentari a cura\smartof}{com\adddot\smartof}}, + byannotator = {{notes a cura\smartof}{n\adddot\smartof}}, + withcommentator = {{amb un comentari a cura\smartof}{amb un com\adddot\smartof}}, + withannotator = {{amb notes a cura\smartof}{amb n\adddot\smartof}}, + withintroduction = {{amb una introducci\'o a cura\smartof}{amb una intr\adddot\smartof}}, + withforeword = {{amb un pr\`oleg a cura\smartof}{amb un pr\`ol\adddot\smartof}}, + withafterword = {{amb un ep\'{\i}leg a cura\smartof}{amb un ep\adddot\smartof}}, + byeditortr = {{edici\'o i traducci\'o \lbx@fromlang\ a cura\smartof}% + {ed\adddotspace i trad\adddotspace\lbx@fromlang\smartof}}, + byeditorco = {{edici\'o i comentari a cura\smartof}% + {ed\adddotspace i com\adddot\smartof}}, + byeditoran = {{edici\'o i notes a cura\smartof}% + {ed\adddotspace i n\adddot\smartof}}, + byeditorin = {{edici\'o i introducci\'o a cura\smartof}% + {ed\adddotspace i intr\adddot\smartof}}, + byeditorfo = {{edici\'o i pr\`oleg a cura\smartof}% + {ed\adddotspace i pr\`ol\adddot\smartof}}, + byeditoraf = {{edici\'o i ep\'{\i}leg a cura\smartof}% + {ed\adddotspace i ep\adddot\smartof}}, + byeditortrco = {{edici\'o, traducci\'o \lbx@fromlang\ i comentari a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i com\adddot\smartof}}, + byeditortran = {{edici\'o, traducci\'o \lbx@fromlang\ i notes a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i n\adddot\smartof}}, + byeditortrin = {{edici\'o, traducci\'o \lbx@fromlang\ i introducci\'o a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i intr\adddot\smartof}}, + byeditortrfo = {{edici\'o, traducci\'o \lbx@fromlang\ i pr\`oleg a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i pr\`ol\adddot\smartof}}, + byeditortraf = {{edici\'o, traducci\'o \lbx@fromlang\ i ep\'{\i}leg a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace\lbx@fromlang\ i ep\adddot\smartof}}, + byeditorcoin = {{edici\'o, comentari i introducci\'o a cura\smartof} + {ed.,\addabbrvspace com\adddotspace i intr\adddot\smartof}}, + byeditorcofo = {{edici\'o, comentari i pr\`oleg a cura\smartof} + {ed.,\addabbrvspace com\adddotspace i pr\`ol\adddot\smartof}}, + byeditorcoaf = {{edici\'o, comentari i ep\'{\i}leg a cura\smartof}% + {ed.,\addabbrvspace com\adddotspace i ep\adddot\smartof}}, + byeditoranin = {{edici\'o, notes i introducci\'o a cura\smartof}% + {ed.,\addabbrvspace n\adddotspace i intr\adddot\smartof}}, + byeditoranfo = {{edici\'o, notes i pr\`oleg a cura\smartof}% + {ed.,\addabbrvspace n\adddotspace i pr\`ol\adddot\smartof}}, + byeditoranaf = {{edici\'o, notes i ep\'{\i}leg a cura\smartof}% + {ed.,\addabbrvspace n\adddotspace i ep\adddot\smartof}}, + byeditortrcoin = {{edici\'o, traducci\'o \lbx@fromlang, comentari i introducci\'o a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace \lbx@fromlang, com\adddotspace i intr\adddot\smartof}}, + byeditortrcofo = {{edici\'o, traducci\'o \lbx@fromlang, comentari i pr\`oleg a cura\smartof}% + {ed.,\addabbrvspace trad\adddotspace \lbx@fromlang, com\adddotspace i pr\`ol\adddot\smartof}}, + byeditortrcoaf = {{edici\'o, traducci\'o \lbx@fromlang, comentari i ep\'{\i}leg a cura\smartof}% + {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, com\adddot\ i ep\adddot\smartof}}, + byeditortranin = {{edici\'o, traducci\'o \lbx@fromlang, notes i introducci\'o a cura\smartof}% + {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i intr\adddot\smartof}}, + byeditortranfo = {{edici\'o, traducci\'o \lbx@fromlang, notes i pr\`oleg a cura\smartof}% + {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i pr\`ol\adddot\smartof}}, + byeditortranaf = {{edici\'o, traducci\'o \lbx@fromlang, notes i ep\'{\i}leg a cura\smartof}% + {ed.,\addabbrvspace trad\adddot\ \lbx@fromlang, n\adddot\ i ep\adddot\smartof}}, + bytranslatorco = {{traducci\'o \lbx@fromlang\ i comentari a cura\smartof}% + {trad\adddot\ \lbx@fromlang\ i com\adddot\smartof}}, + bytranslatoran = {{traducci\'o \lbx@fromlang\ i notes a cura\smartof}% + {trad\adddot\ \lbx@fromlang\ i n\adddot\smartof}}, + bytranslatorin = {{traducci\'o \lbx@fromlang\ i introducci\'o a cura\smartof}% + {trad\adddot\ \lbx@fromlang\ i intr\adddot\smartof}}, + bytranslatorfo = {{traducci\'o \lbx@fromlang\ i pr\`oleg a cura\smartof}% + {trad\adddot\ \lbx@fromlang\ i pr\`ol\adddot\smartof}}, + bytranslatoraf = {{traducci\'o \lbx@fromlang\ i ep\'{\i}leg a cura\smartof}% + {trad\adddot\ \lbx@fromlang\ i ep\adddot\smartof}}, + bytranslatorcoin = {{traducci\'o \lbx@fromlang, comentari i introducci\'o a cura\smartof}% + {trad\adddot\ \lbx@fromlang, com\adddot\ i intr\adddot\smartof}}, + bytranslatorcofo = {{traducci\'o \lbx@fromlang, comentari i pr\`oleg a cura\smartof}% + {trad\adddot\ \lbx@fromlang, com\adddot\ i pr\`ol\adddot\smartof}}, + bytranslatorcoaf = {{traducci\'o \lbx@fromlang, comentari i ep\'{\i}leg a cura\smartof}% + {trad\adddot\ \lbx@fromlang, com\adddot\ i ep\adddot\smartof}}, + bytranslatoranin = {{traducci\'o \lbx@fromlang, notes i introducci\'o a cura\smartof}% + {trad\adddot\ \lbx@fromlang, n\adddot\ i intr\adddot\smartof}}, + bytranslatoranfo = {{traducci\'o \lbx@fromlang, notes i pr\`oleg a cura\smartof}% + {trad\adddot\ \lbx@fromlang, n\adddot\ i pr\`ol\adddot\smartof}}, + bytranslatoranaf = {{traducci\'o \lbx@fromlang, notes i ep\'{\i}leg a cura\smartof}% + {trad\adddot\ \lbx@fromlang, n\adddot\ i ep\adddot\smartof}}, and = {{i}{i}}, andothers = {{et al\adddot}{et al\adddot}}, andmore = {{i m\'es}{i m\'es}}, @@ -373,11 +373,11 @@ oldseries = {{s\`erie antiga}{s\`erie ant\adddot}}, edition = {{edici\'o}{ed\adddot}}, reprint = {{reimpressi\'o}{reimpr\adddot}}, - reprintof = {{reimpressi\'o \smartof}{reimpr\adddotspace\smartof}}, + reprintof = {{reimpressi\'o\smartof}{reimpr\adddot\smartof}}, reprintas = {{reimpr\`es com}{reimpr\adddotspace com}}, - reprintfrom = {{reimpr\`es \smartof}{reimpr\adddotspace\smartof}}, - reviewof = {{ressenya \smartof}{ress\adddotspace\smartof}}, - translationof = {{traducci\'o \smartof}{trad\adddotspace\smartof}}, + reprintfrom = {{reimpr\`es\smartof}{reimpr\adddot\smartof}}, + reviewof = {{ressenya\smartof}{ress\adddot\smartof}}, + translationof = {{traducci\'o\smartof}{trad\adddot\smartof}}, translationas = {{tradu\"{\i}t com}{trad\adddotspace com}}, translationfrom = {{tradu\"{\i}t del}{trad\adddotspace del}}, % Unsure of 'del' origpubas = {{publicat origin\`ariament com}{pub\adddotspace orig\adddotspace com}}, diff --git a/macros/latex/contrib/biblatex/latex/lbx/english.lbx b/macros/latex/contrib/biblatex/latex/lbx/english.lbx index 1ade8c7f81..d13bd0fd42 100644 --- a/macros/latex/contrib/biblatex/latex/lbx/english.lbx +++ b/macros/latex/contrib/biblatex/latex/lbx/english.lbx @@ -470,6 +470,7 @@ canadian,australian,newzealand,USenglish,UKenglish} november = {{November}{Nov\adddot}}, december = {{December}{Dec\adddot}}, langamerican = {{American}{American}}, + langbasque = {{Basque}{Basque}}, langbrazilian = {{Brazilian}{Brazilian}}, langbulgarian = {{Bulgarian}{Bulgarian}}, langcatalan = {{Catalan}{Catalan}}, @@ -502,6 +503,7 @@ canadian,australian,newzealand,USenglish,UKenglish} langturkish = {{Turkish}{Turkish}}, langukrainian = {{Ukrainian}{Ukrainian}}, fromamerican = {{from the American}{from the American}}, + frombasque = {{from the Basque}{from the Basque}}, frombrazilian = {{from the Brazilian}{from the Brazilian}}, frombulgarian = {{from the Bulgarian}{from the Bulgarian}}, fromcatalan = {{from the Catalan}{from the Catalan}}, diff --git a/macros/latex/contrib/biblatex/latex/lbx/french.lbx b/macros/latex/contrib/biblatex/latex/lbx/french.lbx index d2e441b66e..8b3f7f194b 100644 --- a/macros/latex/contrib/biblatex/latex/lbx/french.lbx +++ b/macros/latex/contrib/biblatex/latex/lbx/french.lbx @@ -276,23 +276,23 @@ organizers = {{organisateurs}{org\adddot}},% byorganizer = {{organis\'e par}{org\adddotspace par}},% byauthor = {{par}{par}}, - byeditor = {{sous la direction \smartof}{sous la dir\adddotspace\smartof}}, + byeditor = {{sous la direction\smartof}{sous la dir\adddot\smartof}}, bycompiler = {{compil\'e par}{comp\adddotspace par}}, byredactor = {{r\'edig\'e par}{r\'ed\adddotspace par}}, byreviser = {{r\'evis\'e par}{r\'ev\adddotspace par}}, byreviewer = {{examin\'e par}{ex\adddotspace par}}, byfounder = {{d\'ecouvert par}{d\'ecouv\adddotspace par}}, bycontinuator = {{continu\'e par}{cont\adddotspace par}}, - bycollaborator = {{avec la collaboration \smartof}{avec la - coll\adddotspace\smartof}}, + bycollaborator = {{avec la collaboration\smartof}{avec la + coll\adddot\smartof}}, bytranslator = {{traduit \lbx@lfromlang\ par}{trad\adddotspace \lbx@sfromlang\ par}}, bycommentator = {{comment\'e par}{comm\adddotspace par}}, byannotator = {{annot\'e par}{annot\adddotspace par}}, - withcommentator = {{avec des commentaires \smartof}{avec des comment\adddotspace\smartof}}, - withannotator = {{avec des annotations \smartof}{avec des annot\adddotspace\smartof}}, - withintroduction = {{avec une introduction \smartof}{avec une introd\adddotspace\smartof}}, - withforeword = {{avec une pr\'eface \smartof}{avec une pr\'ef\adddotspace\smartof}}, - withafterword = {{avec une postface \smartof}{avec une postf\adddotspace\smartof}}, + withcommentator = {{avec des commentaires\smartof}{avec des comment\adddot\smartof}}, + withannotator = {{avec des annotations\smartof}{avec des annot\adddot\smartof}}, + withintroduction = {{avec une introduction\smartof}{avec une introd\adddot\smartof}}, + withforeword = {{avec une pr\'eface\smartof}{avec une pr\'ef\adddot\smartof}}, + withafterword = {{avec une postface\smartof}{avec une postf\adddot\smartof}}, byeditortr = {{\'edition \'etablie et traduite \lbx@lfromlang\ par}% {\'ed\adddotspace \'etablie et trad\adddotspace \lbx@sfromlang\ par}}, byeditorco = {{\'edition \'etablie et comment\'ee par}% @@ -378,7 +378,7 @@ reprint = {{r\'eimpression}{r\'eimpr\adddot}}, reprintof = {{r\'eimpression de}{r\'eimpr\adddotspace de}}, reprintas = {{r\'eimpression sous le titre}{r\'eimpr\adddotspace sous le titre}}, - reprintfrom = {{r\'eimpression \`a partir \smartof}{r\'eimpr\adddotspace \`a part\adddotspace\smartof}}, + reprintfrom = {{r\'eimpression \`a partir\smartof}{r\'eimpr\adddotspace \`a part\adddot\smartof}}, translationof = {{traduction de}{trad\adddotspace de}}, translationas = {{traduit sous le titre}{trad\adddotspace sous le titre}}, translationfrom = {{traduit de}{trad\adddotspace de}}, diff --git a/macros/latex/contrib/biblatex/latex/lbx/german.lbx b/macros/latex/contrib/biblatex/latex/lbx/german.lbx index 3aba7d6739..d09bee3a76 100644 --- a/macros/latex/contrib/biblatex/latex/lbx/german.lbx +++ b/macros/latex/contrib/biblatex/latex/lbx/german.lbx @@ -455,6 +455,7 @@ november = {{November}{Nov\adddot}}, december = {{Dezember}{Dez\adddot}}, langamerican = {{Amerikanisch}{Amerikanisch}}, + langbasque = {{Baskisch}{Baskisch}}, langbrazilian = {{Brasilianisch}{Brasilianisch}}, langbulgarian = {{Bulgarisch}{Bulgarisch}}, langcatalan = {{Katalanisch}{Katalanisch}}, @@ -487,6 +488,7 @@ langturkish = {{T\"urkisch}{T\"urkisch}}, langukrainian = {{Ukrainisch}{Ukrainisch}}, fromamerican = {{aus dem Amerikanischen}{aus dem Amerikanischen}}, + frombasque = {{aus dem Baskischen}{aus dem Baskischen}}, frombrazilian = {{aus dem Brasilianischen}{aus dem Brasilianischen}}, frombulgarian = {{aus dem Bulgarischen}{aus dem Bulgarischen}}, fromcatalan = {{aus dem Katalanischen}{aus dem Katalanischen}}, diff --git a/macros/luatex/generic/lualibs/NEWS b/macros/luatex/generic/lualibs/NEWS index af54318e6e..4c80d06987 100644 --- a/macros/luatex/generic/lualibs/NEWS +++ b/macros/luatex/generic/lualibs/NEWS @@ -1,4 +1,7 @@ History of the lualibs package +2020/12/30 v2.73/ + * sync with Context current as of 2020/12/30. + 2020/08/31 v2.72/ * sync with Context current as of 2020/08/31. diff --git a/macros/luatex/generic/lualibs/README.md b/macros/luatex/generic/lualibs/README.md index 351930040c..cf330df159 100644 --- a/macros/luatex/generic/lualibs/README.md +++ b/macros/luatex/generic/lualibs/README.md @@ -1,10 +1,10 @@ # The Lualibs Package -VERSION: 2.72 +VERSION: 2.73 -DATE: 2020-08-31 +DATE: 2020-12-30 -FONTLOADERDATE: 2020-08-31 +FONTLOADERDATE: 2020-12-30 Lualibs is a collection of Lua modules useful for general programming. diff --git a/macros/luatex/generic/lualibs/lualibs-basic-merged.lua b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua index 147cc33fa9..92e571a7cc 100644 --- a/macros/luatex/generic/lualibs/lualibs-basic-merged.lua +++ b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua @@ -1,6 +1,6 @@ -- merged file : lualibs-basic-merged.lua -- parent file : lualibs-basic.lua --- merge date : Mon Aug 31 23:16:26 2020 +-- merge date : Wed Dec 30 17:55:54 2020 do -- begin closure to overcome local limits and interference @@ -358,7 +358,10 @@ methods["already loaded"]=function(name) return package.loaded[name] end methods["preload table"]=function(name) - return builtin["preload table"](name) + local f=builtin["preload table"] + if f then + return f(name) + end end methods["qualified path"]=function(name) return loadedbyname(addsuffix(lualibfile(name),"lua"),name) @@ -370,15 +373,24 @@ methods["lib extra list"]=function(name) return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib") end methods["path specification"]=function(name) - getluapaths() - return builtin["path specification"](name) + local f=builtin["path specification"] + if f then + getluapaths() + return f(name) + end end methods["cpath specification"]=function(name) - getlibpaths() - return builtin["cpath specification"](name) + local f=builtin["cpath specification"] + if f then + getlibpaths() + return f(name) + end end methods["all in one fallback"]=function(name) - return builtin["all in one fallback"](name) + local f=builtin["all in one fallback"] + if f then + return f(name) + end end methods["not loaded"]=function(name) if helpers.trace then @@ -3358,6 +3370,8 @@ elseif name=="macosx" then platform="osx-intel" elseif find(architecture,"x86_64",1,true) then platform="osx-64" + elseif find(architecture,"arm64",1,true) then + platform="osx-64" else platform="osx-ppc" end @@ -4684,6 +4698,7 @@ if not modules then modules={} end modules ['l-unicode']={ license="see context related readme files" } utf=utf or {} +-- unicode=nil if not string.utfcharacters then local gmatch=string.gmatch function string.characters(str) diff --git a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua index 89d384ac8a..cac8889ca3 100644 --- a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua +++ b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua @@ -1,6 +1,6 @@ -- merged file : lualibs-extended-merged.lua -- parent file : lualibs-extended.lua --- merge date : Mon Aug 31 23:16:16 2020 +-- merge date : Wed Dec 30 17:55:44 2020 do -- begin closure to overcome local limits and interference @@ -2700,8 +2700,6 @@ local dimenfactors=allocate { ["pc"]=(1/12)/65536, ["dd"]=(1157/1238)/65536, ["cc"]=(1157/14856)/65536, - ["nd"]=(20320/21681)/65536, - ["nc"]=(5080/65043)/65536 } local f_none=formatters["%s%s"] local f_true=formatters["%0.5F%s"] @@ -2733,8 +2731,6 @@ function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end -function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end -function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0") local unit=R("az")^1+P("%") local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1)) diff --git a/macros/luatex/generic/lualibs/lualibs-os.lua b/macros/luatex/generic/lualibs/lualibs-os.lua index 1e01350947..73841074c4 100644 --- a/macros/luatex/generic/lualibs/lualibs-os.lua +++ b/macros/luatex/generic/lualibs/lualibs-os.lua @@ -358,6 +358,8 @@ elseif name == "macosx" then platform = "osx-intel" elseif find(architecture,"x86_64",1,true) then platform = "osx-64" + elseif find(architecture,"arm64",1,true) then + platform = "osx-64" else platform = "osx-ppc" end diff --git a/macros/luatex/generic/lualibs/lualibs-package.lua b/macros/luatex/generic/lualibs/lualibs-package.lua index 94607d4368..a35ec3e2a9 100644 --- a/macros/luatex/generic/lualibs/lualibs-package.lua +++ b/macros/luatex/generic/lualibs/lualibs-package.lua @@ -300,7 +300,10 @@ methods["already loaded"] = function(name) end methods["preload table"] = function(name) - return builtin["preload table"](name) + local f = builtin["preload table"] + if f then + return f(name) + end end methods["qualified path"]=function(name) @@ -316,17 +319,26 @@ methods["lib extra list"] = function(name) end methods["path specification"] = function(name) - getluapaths() -- triggers list building and tracing - return builtin["path specification"](name) + local f = builtin["path specification"] + if f then + getluapaths() -- triggers list building and tracing + return f(name) + end end methods["cpath specification"] = function(name) - getlibpaths() -- triggers list building and tracing - return builtin["cpath specification"](name) + local f = builtin["cpath specification"] + if f then + getlibpaths() -- triggers list building and tracing + return f(name) + end end methods["all in one fallback"] = function(name) - return builtin["all in one fallback"](name) + local f = builtin["all in one fallback"] + if f then + return f(name) + end end methods["not loaded"] = function(name) diff --git a/macros/luatex/generic/lualibs/lualibs-util-dim.lua b/macros/luatex/generic/lualibs/lualibs-util-dim.lua index 76b5fd20bb..bb9eca9668 100644 --- a/macros/luatex/generic/lualibs/lualibs-util-dim.lua +++ b/macros/luatex/generic/lualibs/lualibs-util-dim.lua @@ -44,8 +44,8 @@ local dimenfactors = allocate { ["pc"] = ( 1/ 12)/65536, ["dd"] = ( 1157/ 1238)/65536, ["cc"] = ( 1157/14856)/65536, - ["nd"] = (20320/21681)/65536, - ["nc"] = ( 5080/65043)/65536 + -- ["nd"] = (20320/21681)/65536, + -- ["nc"] = ( 5080/65043)/65536 } -- print(table.serialize(dimenfactors)) @@ -61,9 +61,9 @@ local dimenfactors = allocate { -- ["ex"]=6.103515625e-005, -- ["in"]=2.1113586636917117e-007, -- ["mm"]=5.3628510057769473e-008, --- ["nc"]=1.1917446679504327e-006, --- ["nd"]=1.4300936015405194e-005, --- ["pc"]=1.2715657552083333e-006, +-- --["nc"]=1.1917446679504327e-006, +-- --["nd"]=1.4300936015405194e-005, +-- --["pc"]=1.2715657552083333e-006, -- ["pt"]=1.52587890625e-005, -- ["sp"]=1, -- } @@ -79,8 +79,8 @@ local dimenfactors = allocate { -- ["ex"]=0.00006103515625, -- ["in"]=0.00000021113587, -- ["mm"]=0.00000005362851, --- ["nc"]=0.00000119174467, --- ["nd"]=0.00001430093602, +-- --["nc"]=0.00000119174467, +-- --["nd"]=0.00001430093602, -- ["pc"]=0.00000127156576, -- ["pt"]=0.00001525878906, -- ["sp"]=1, @@ -128,8 +128,8 @@ function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end -function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end -function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end +-------- number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end +-------- number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end --[[ldx--

More interesting it to implement a (sort of) dimen datatype, one diff --git a/macros/luatex/generic/lualibs/lualibs.dtx b/macros/luatex/generic/lualibs/lualibs.dtx index c98c752765..7246e8541e 100644 --- a/macros/luatex/generic/lualibs/lualibs.dtx +++ b/macros/luatex/generic/lualibs/lualibs.dtx @@ -37,7 +37,7 @@ \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} -\Msg{* Package: lualibs 2020-08-31 v2.72 Lua additional functions.} +\Msg{* Package: lualibs 2020-12-30 v2.73 Lua additional functions.} \Msg{************************************************************************} \keepsilent @@ -107,7 +107,7 @@ and lualibs-extended.lua. %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{lualibs.drv} - [2020/08/31 v2.72 Lua Libraries.] + [2020/12/30 v2.73 Lua Libraries.] \documentclass{ltxdoc} \usepackage{fancyvrb,xspace} \usepackage[x11names]{xcolor} @@ -208,7 +208,7 @@ and lualibs-extended.lua. % \GetFileInfo{lualibs.drv} % % \title{The \identifier{lualibs} package} -% \date{2020/08/31 v2.72} +% \date{2020/12/30 v2.73} % \author{Élie Roux · \email{elie.roux@telecom-bretagne.eu}\\ % Philipp Gesang · \email{phg@phi-gamma.net}\\ % The \LaTeX3 Project · \email{https://github.com/latex3/lualibs/}\\ @@ -429,8 +429,8 @@ lualibs = lualibs or { } lualibs.module_info = { name = "lualibs", - version = "2.72", --TAGVERSION - date = "2020-08-31", --TAGDATE + version = "2.73", --TAGVERSION + date = "2020-12-30", --TAGDATE description = "ConTeXt Lua standard libraries.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -583,8 +583,8 @@ local loadmodule = lualibs.loadmodule local lualibs_basic_module = { name = "lualibs-basic", - version = "2.72", --TAGVERSION - date = "2020-08-31", --TAGDATE + version = "2.73", --TAGVERSION + date = "2020-12-30", --TAGDATE description = "ConTeXt Lua libraries -- basic collection.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -665,8 +665,8 @@ lualibs = lualibs or { } local lualibs_extended_module = { name = "lualibs-extended", - version = "2.72", --TAGVERSION - date = "2020-08-31", --TAGDATE + version = "2.73", --TAGVERSION + date = "2020-12-30", --TAGDATE description = "ConTeXt Lua libraries -- extended collection.", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang", copyright = "PRAGMA ADE / ConTeXt Development Team", diff --git a/macros/luatex/generic/lualibs/lualibs.pdf b/macros/luatex/generic/lualibs/lualibs.pdf index 031fc8158e..10274b447b 100644 Binary files a/macros/luatex/generic/lualibs/lualibs.pdf and b/macros/luatex/generic/lualibs/lualibs.pdf differ diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS index 658c5d420e..b0a7f124c1 100644 --- a/macros/luatex/generic/luaotfload/NEWS +++ b/macros/luatex/generic/luaotfload/NEWS @@ -1,6 +1,32 @@ Change History -------------- -2020-08-31 luaotfload v3.15 +2020-12-31 luaotfload v3.16 + + * The fontloader has been synced with the context code from 2020-12-30 + * The entry point is called luaotfload.lua instead of + luaotfload-main.lua (but the old name is still provided for + compatibility). + * pre/post_shaping_filter callbacks has been added. + * The number of lua-files and submodules shown in the log-file + has been reduced. But it is extended again by setting the environment + variable LUAOTFLOAD_TRACE_SUBMODULES=1. + * The HarfBuzz based shaper will in some situations drop hyphenation + points. This happens less frequently now since the new version uses + first/second discretionaries (the mechanism described in the LuaTeX manual, + section 5.6 for the of-f-ice example) to support a limited amount of + nesting. + * When the node shaper is used, experimental support for + OpenType variable fonts has been added. To use them, set the font + feature axis to a comma separated list of axis names and values. + (E.g. axis={weight=600}) The supported axis names and value + range depend on the font. + * The font features upper and lower can be used to map + the text of a font to upper or lowercase before displaying it. Currently + this implements the untailored Unicode case mapping algorithm, but it is + planned to add tailoring later. + * A number of small bugfixes. + +2020-09-02 luaotfload v3.15 * The font database is updated more reliably if fonts get deleted. * In multiple error cases, error messages are shown instead of silently generating bad output. diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md index 626e1c9b8b..f19c4c5563 100644 --- a/macros/luatex/generic/luaotfload/README.md +++ b/macros/luatex/generic/luaotfload/README.md @@ -1,8 +1,8 @@ # The Luaotfload Package -VERSION: 3.15 +VERSION: 3.16 -DATE: 2020-09-02 +DATE: 2020-12-31 ## Description diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf index 5e90db1544..ac40ce55f9 100644 Binary files a/macros/luatex/generic/luaotfload/filegraph.pdf and b/macros/luatex/generic/luaotfload/filegraph.pdf differ diff --git a/macros/luatex/generic/luaotfload/filegraph.tex b/macros/luatex/generic/luaotfload/filegraph.tex index ee76912b78..1301319880 100644 --- a/macros/luatex/generic/luaotfload/filegraph.tex +++ b/macros/luatex/generic/luaotfload/filegraph.tex @@ -103,7 +103,7 @@ label={[name=mL3,font=\itshape,anchor=south]above:Lualibs -- Lua Libraries from %>>>>>>>>>>>>>>>> }; % m4 -\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload-main.lua}; +\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload.lua}; % m5 \node[fill=gray!20,draw=gray!30,dashed,basic,inner sep=6mm,anchor=south west] at (m3.south -| m2.west)(m5){% diff --git a/macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua b/macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua deleted file mode 100644 index 01e1f8300c..0000000000 --- a/macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua +++ /dev/null @@ -1,35049 +0,0 @@ ---[[info----------------------------------------------------------------------- - Luaotfload fontloader package - build 2020-08-31 23:33:48 -------------------------------------------------------------------------------- - - © 2020 PRAGMA ADE / ConTeXt Development Team - - The code in this file is provided under the GPL v2.0 license. See the - file COPYING in the Luaotfload repository for details. - - Report bugs to https://github.com/latex3/luaotfload - - This file has been assembled from components taken from Context. See - the Luaotfload documentation for details: - - $ texdoc luaotfload - $ man 1 luaotfload-tool - $ man 5 luaotfload.conf - - Included files: - - · fontloader-data-con.lua - · fontloader-basics-nod.lua - · fontloader-basics-chr.lua - · fontloader-font-ini.lua - · fontloader-fonts-mis.lua - · fontloader-font-con.lua - · fontloader-fonts-enc.lua - · fontloader-font-cid.lua - · fontloader-font-map.lua - · fontloader-font-vfc.lua - · fontloader-font-otr.lua - · fontloader-font-oti.lua - · fontloader-font-ott.lua - · fontloader-font-cff.lua - · fontloader-font-ttf.lua - · fontloader-font-dsp.lua - · fontloader-font-oup.lua - · fontloader-font-otl.lua - · fontloader-font-oto.lua - · fontloader-font-otj.lua - · fontloader-font-ota.lua - · fontloader-font-ots.lua - · fontloader-font-osd.lua - · fontloader-font-ocl.lua - · fontloader-font-otc.lua - · fontloader-font-onr.lua - · fontloader-font-one.lua - · fontloader-font-afk.lua - · fontloader-fonts-tfm.lua - · fontloader-font-lua.lua - · fontloader-font-def.lua - · fontloader-font-shp.lua - · fontloader-fonts-def.lua - · fontloader-fonts-ext.lua - · fontloader-font-imp-tex.lua - · fontloader-font-imp-ligatures.lua - · fontloader-font-imp-italics.lua - · fontloader-font-imp-effects.lua - · fontloader-fonts-lig.lua - · fontloader-fonts-gbn.lua - ---info]]----------------------------------------------------------------------- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] --- - -if not modules then modules={} end modules ['data-con']={ - version=1.100, - comment="companion to luat-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local setmetatable=setmetatable -local format,lower,gsub=string.format,string.lower,string.gsub -local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) -local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) -local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end) -containers=containers or {} -local containers=containers -containers.usecache=true -local getwritablepath=caches.getwritablepath -local getreadablepaths=caches.getreadablepaths -local cacheiswritable=caches.is_writable -local loaddatafromcache=caches.loaddata -local savedataincache=caches.savedata -local report_containers=logs.reporter("resolvers","containers") -local allocated={} -local mt={ - __index=function(t,k) - if k=="writable" then - local writable=getwritablepath(t.category,t.subcategory) or { "." } - t.writable=writable - return writable - elseif k=="readables" then - local readables=getreadablepaths(t.category,t.subcategory) or { "." } - t.readables=readables - return readables - end - end, - __storage__=true -} -function containers.define(category,subcategory,version,enabled) - if category and subcategory then - local c=allocated[category] - if not c then - c={} - allocated[category]=c - end - local s=c[subcategory] - if not s then - s={ - category=category, - subcategory=subcategory, - storage={}, - enabled=enabled, - version=version or math.pi, - trace=false, - } - setmetatable(s,mt) - c[subcategory]=s - end - return s - end -end -function containers.is_usable(container,name) - return container.enabled and caches and cacheiswritable(container.writable,name) -end -function containers.is_valid(container,name) - if name and name~="" then - local storage=container.storage[name] - return storage and storage.cache_version==container.version - else - return false - end -end -function containers.read(container,name) - local storage=container.storage - local stored=storage[name] - if not stored and container.enabled and caches and containers.usecache then - stored=loaddatafromcache(container.readables,name,container.writable) - if stored and stored.cache_version==container.version then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","load",container.subcategory,name) - end - else - stored=nil - end - storage[name]=stored - elseif stored then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) - end - end - return stored -end -function containers.write(container,name,data,fast) - if data then - data.cache_version=container.version - if container.enabled and caches then - local unique=data.unique - local shared=data.shared - data.unique=nil - data.shared=nil - savedataincache(container.writable,name,data,fast) - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","save",container.subcategory,name) - end - data.unique=unique - data.shared=shared - end - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","store",container.subcategory,name) - end - container.storage[name]=data - end - return data -end -function containers.content(container,name) - return container.storage[name] -end -function containers.cleanname(name) - return (gsub(lower(name),"[^%w\128-\255]+","-")) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod” e296bfb03d5654a596b43612348c4191] --- - -if not modules then modules={} end modules ['luatex-fonts-nod']={ - version=1.001, - comment="companion to luatex-fonts.lua", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -if tex.attribute[0]~=0 then - texio.write_nl("log","!") - texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") - texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") - texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") - texio.write_nl("log","!") - tex.attribute[0]=0 -end -attributes=attributes or {} -attributes.unsetvalue=-0x7FFFFFFF -local numbers,last={},127 -attributes.private=attributes.private or function(name) - local number=numbers[name] - if not number then - if last<255 then - last=last+1 - end - number=last - numbers[name]=number - end - return number -end -nodes={} -nodes.handlers={} -local nodecodes={} -local glyphcodes=node.subtypes("glyph") -local disccodes=node.subtypes("disc") -for k,v in next,node.types() do - v=string.gsub(v,"_","") - nodecodes[k]=v - nodecodes[v]=k -end -for k,v in next,glyphcodes do - glyphcodes[v]=k -end -for k,v in next,disccodes do - disccodes[v]=k -end -nodes.nodecodes=nodecodes -nodes.glyphcodes=glyphcodes -nodes.disccodes=disccodes -nodes.dirvalues={ lefttoright=0,righttoleft=1 } -nodes.handlers.protectglyphs=node.protect_glyphs -nodes.handlers.unprotectglyphs=node.unprotect_glyphs -local direct=node.direct -local nuts={} -nodes.nuts=nuts -local tonode=direct.tonode -local tonut=direct.todirect -nodes.tonode=tonode -nodes.tonut=tonut -nuts.tonode=tonode -nuts.tonut=tonut -nuts.getattr=direct.get_attribute -nuts.getboth=direct.getboth -nuts.getchar=direct.getchar -nuts.getdirection=direct.getdirection -nuts.getdisc=direct.getdisc -nuts.getreplace=direct.getreplace -nuts.getfield=direct.getfield -nuts.getfont=direct.getfont -nuts.getid=direct.getid -nuts.getkern=direct.getkern -nuts.getlist=direct.getlist -nuts.getnext=direct.getnext -nuts.getoffsets=direct.getoffsets -nuts.getprev=direct.getprev -nuts.getsubtype=direct.getsubtype -nuts.getwidth=direct.getwidth -nuts.setattr=direct.setfield -nuts.setboth=direct.setboth -nuts.setchar=direct.setchar -nuts.setcomponents=direct.setcomponents -nuts.setdirection=direct.setdirection -nuts.setdisc=direct.setdisc -nuts.setreplace=direct.setreplace -nuts.setfield=setfield -nuts.setkern=direct.setkern -nuts.setlink=direct.setlink -nuts.setlist=direct.setlist -nuts.setnext=direct.setnext -nuts.setoffsets=direct.setoffsets -nuts.setprev=direct.setprev -nuts.setsplit=direct.setsplit -nuts.setsubtype=direct.setsubtype -nuts.setwidth=direct.setwidth -nuts.getglyphdata=nuts.getattr -nuts.setglyphdata=nuts.setattr -nuts.ischar=direct.is_char -nuts.isglyph=direct.is_glyph -nuts.copy=direct.copy -nuts.copy_list=direct.copy_list -nuts.copy_node=direct.copy -nuts.end_of_math=direct.end_of_math -nuts.flush=direct.flush -nuts.flush_list=direct.flush_list -nuts.flush_node=direct.flush_node -nuts.free=direct.free -nuts.insert_after=direct.insert_after -nuts.insert_before=direct.insert_before -nuts.is_node=direct.is_node -nuts.kerning=direct.kerning -nuts.ligaturing=direct.ligaturing -nuts.new=direct.new -nuts.remove=direct.remove -nuts.tail=direct.tail -nuts.traverse=direct.traverse -nuts.traverse_char=direct.traverse_char -nuts.traverse_glyph=direct.traverse_glyph -nuts.traverse_id=direct.traverse_id -local propertydata=direct.get_properties_table() -nodes.properties={ data=propertydata } -if direct.set_properties_mode then - direct.set_properties_mode(true,true) - function direct.set_properties_mode() end -end -nuts.getprop=function(n,k) - local p=propertydata[n] - if p then - return p[k] - end -end -nuts.setprop=function(n,k,v) - if v then - local p=propertydata[n] - if p then - p[k]=v - else - propertydata[n]={ [k]=v } - end - end -end -nodes.setprop=nodes.setproperty -nodes.getprop=nodes.getproperty -local setprev=nuts.setprev -local setnext=nuts.setnext -local getnext=nuts.getnext -local setlink=nuts.setlink -local getfield=nuts.getfield -local setfield=nuts.setfield -local getsubtype=nuts.getsubtype -local isglyph=nuts.isglyph -local find_tail=nuts.tail -local flush_list=nuts.flush_list -local flush_node=nuts.flush_node -local traverse_id=nuts.traverse_id -local copy_node=nuts.copy_node -local glyph_code=nodes.nodecodes.glyph -local ligature_code=nodes.glyphcodes.ligature -do - local get_components=node.direct.getcomponents - local set_components=node.direct.setcomponents - local function copy_no_components(g,copyinjection) - local components=get_components(g) - if components then - set_components(g) - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - set_components(g,components) - return n - else - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - return n - end - end - local function copy_only_glyphs(current) - local head=nil - local previous=nil - for n in traverse_id(glyph_code,current) do - n=copy_node(n) - if head then - setlink(previous,n) - else - head=n - end - previous=n - end - return head - end - local function count_components(start,marks) - local char=isglyph(start) - if char then - if getsubtype(start)==ligature_code then - local n=0 - local components=get_components(start) - while components do - n=n+count_components(components,marks) - components=getnext(components) - end - return n - elseif not marks[char] then - return 1 - end - end - return 0 - end - nuts.set_components=set_components - nuts.get_components=get_components - nuts.copy_only_glyphs=copy_only_glyphs - nuts.copy_no_components=copy_no_components - nuts.count_components=count_components -end -nuts.uses_font=direct.uses_font -do - local dummy=tonut(node.new("glyph")) - nuts.traversers={ - glyph=nuts.traverse_id(nodecodes.glyph,dummy), - glue=nuts.traverse_id(nodecodes.glue,dummy), - disc=nuts.traverse_id(nodecodes.disc,dummy), - boundary=nuts.traverse_id(nodecodes.boundary,dummy), - char=nuts.traverse_char(dummy), - node=nuts.traverse(dummy), - } -end -if not nuts.setreplace then - local getdisc=nuts.getdisc - local setfield=nuts.setfield - function nuts.getreplace(n) - local _,_,h,_,_,t=getdisc(n,true) - return h,t - end - function nuts.setreplace(n,h) - setfield(n,"replace",h) - end -end -do - local getsubtype=nuts.getsubtype - function nuts.start_of_par(n) - local s=getsubtype(n) - return s==0 or s==2 - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- - - -characters=characters or {} -characters.blockrange={} -characters.classifiers={ - [768]=5, - [769]=5, - [770]=5, - [771]=5, - [772]=5, - [773]=5, - [774]=5, - [775]=5, - [776]=5, - [777]=5, - [778]=5, - [779]=5, - [780]=5, - [781]=5, - [782]=5, - [783]=5, - [784]=5, - [785]=5, - [786]=5, - [787]=5, - [788]=5, - [789]=5, - [790]=5, - [791]=5, - [792]=5, - [793]=5, - [794]=5, - [795]=5, - [796]=5, - [797]=5, - [798]=5, - [799]=5, - [800]=5, - [801]=5, - [802]=5, - [803]=5, - [804]=5, - [805]=5, - [806]=5, - [807]=5, - [808]=5, - [809]=5, - [810]=5, - [811]=5, - [812]=5, - [813]=5, - [814]=5, - [815]=5, - [816]=5, - [817]=5, - [818]=5, - [819]=5, - [820]=5, - [821]=5, - [822]=5, - [823]=5, - [824]=5, - [825]=5, - [826]=5, - [827]=5, - [828]=5, - [829]=5, - [830]=5, - [831]=5, - [832]=5, - [833]=5, - [834]=5, - [835]=5, - [836]=5, - [837]=5, - [838]=5, - [839]=5, - [840]=5, - [841]=5, - [842]=5, - [843]=5, - [844]=5, - [845]=5, - [846]=5, - [847]=5, - [848]=5, - [849]=5, - [850]=5, - [851]=5, - [852]=5, - [853]=5, - [854]=5, - [855]=5, - [856]=5, - [857]=5, - [858]=5, - [859]=5, - [860]=5, - [861]=5, - [862]=5, - [863]=5, - [864]=5, - [865]=5, - [866]=5, - [867]=5, - [868]=5, - [869]=5, - [870]=5, - [871]=5, - [872]=5, - [873]=5, - [874]=5, - [875]=5, - [876]=5, - [877]=5, - [878]=5, - [879]=5, - [1155]=5, - [1156]=5, - [1157]=5, - [1158]=5, - [1159]=5, - [1425]=5, - [1426]=5, - [1427]=5, - [1428]=5, - [1429]=5, - [1430]=5, - [1431]=5, - [1432]=5, - [1433]=5, - [1434]=5, - [1435]=5, - [1436]=5, - [1437]=5, - [1438]=5, - [1439]=5, - [1440]=5, - [1441]=5, - [1442]=5, - [1443]=5, - [1444]=5, - [1445]=5, - [1446]=5, - [1447]=5, - [1448]=5, - [1449]=5, - [1450]=5, - [1451]=5, - [1452]=5, - [1453]=5, - [1454]=5, - [1455]=5, - [1456]=5, - [1457]=5, - [1458]=5, - [1459]=5, - [1460]=5, - [1461]=5, - [1462]=5, - [1463]=5, - [1464]=5, - [1465]=5, - [1466]=5, - [1467]=5, - [1468]=5, - [1469]=5, - [1471]=5, - [1473]=5, - [1474]=5, - [1476]=5, - [1477]=5, - [1479]=5, - [1536]=4, - [1537]=4, - [1538]=4, - [1539]=4, - [1540]=4, - [1541]=4, - [1542]=6, - [1543]=6, - [1544]=4, - [1545]=6, - [1546]=6, - [1547]=4, - [1548]=6, - [1549]=6, - [1550]=6, - [1551]=6, - [1552]=5, - [1553]=5, - [1554]=5, - [1555]=5, - [1556]=5, - [1557]=5, - [1558]=5, - [1559]=5, - [1560]=5, - [1561]=5, - [1562]=5, - [1563]=6, - [1564]=6, - [1566]=6, - [1567]=6, - [1568]=2, - [1569]=4, - [1570]=3, - [1571]=3, - [1572]=3, - [1573]=3, - [1574]=2, - [1575]=3, - [1576]=2, - [1577]=3, - [1578]=2, - [1579]=2, - [1580]=2, - [1581]=2, - [1582]=2, - [1583]=3, - [1584]=3, - [1585]=3, - [1586]=3, - [1587]=2, - [1588]=2, - [1589]=2, - [1590]=2, - [1591]=2, - [1592]=2, - [1593]=2, - [1594]=2, - [1595]=2, - [1596]=2, - [1597]=2, - [1598]=2, - [1599]=2, - [1600]=2, - [1601]=2, - [1602]=2, - [1603]=2, - [1604]=2, - [1605]=2, - [1606]=2, - [1607]=2, - [1608]=3, - [1609]=2, - [1610]=2, - [1611]=5, - [1612]=5, - [1613]=5, - [1614]=5, - [1615]=5, - [1616]=5, - [1617]=5, - [1618]=5, - [1619]=5, - [1620]=5, - [1621]=5, - [1622]=5, - [1623]=5, - [1624]=5, - [1625]=5, - [1626]=5, - [1627]=5, - [1628]=5, - [1629]=5, - [1630]=5, - [1631]=5, - [1632]=6, - [1633]=6, - [1634]=6, - [1635]=6, - [1636]=6, - [1637]=6, - [1638]=6, - [1639]=6, - [1640]=6, - [1641]=6, - [1642]=6, - [1643]=6, - [1644]=6, - [1645]=6, - [1646]=2, - [1647]=2, - [1648]=5, - [1649]=3, - [1650]=3, - [1651]=3, - [1652]=4, - [1653]=3, - [1654]=3, - [1655]=3, - [1656]=2, - [1657]=2, - [1658]=2, - [1659]=2, - [1660]=2, - [1661]=2, - [1662]=2, - [1663]=2, - [1664]=2, - [1665]=2, - [1666]=2, - [1667]=2, - [1668]=2, - [1669]=2, - [1670]=2, - [1671]=2, - [1672]=3, - [1673]=3, - [1674]=3, - [1675]=3, - [1676]=3, - [1677]=3, - [1678]=3, - [1679]=3, - [1680]=3, - [1681]=3, - [1682]=3, - [1683]=3, - [1684]=3, - [1685]=3, - [1686]=3, - [1687]=3, - [1688]=3, - [1689]=3, - [1690]=2, - [1691]=2, - [1692]=2, - [1693]=2, - [1694]=2, - [1695]=2, - [1696]=2, - [1697]=2, - [1698]=2, - [1699]=2, - [1700]=2, - [1701]=2, - [1702]=2, - [1703]=2, - [1704]=2, - [1705]=2, - [1706]=2, - [1707]=2, - [1708]=2, - [1709]=2, - [1710]=2, - [1711]=2, - [1712]=2, - [1713]=2, - [1714]=2, - [1715]=2, - [1716]=2, - [1717]=2, - [1718]=2, - [1719]=2, - [1720]=2, - [1721]=2, - [1722]=2, - [1723]=2, - [1724]=2, - [1725]=2, - [1726]=2, - [1727]=2, - [1728]=3, - [1729]=2, - [1730]=2, - [1731]=3, - [1732]=3, - [1733]=3, - [1734]=3, - [1735]=3, - [1736]=3, - [1737]=3, - [1738]=3, - [1739]=3, - [1740]=2, - [1741]=3, - [1742]=2, - [1743]=3, - [1744]=2, - [1745]=2, - [1746]=3, - [1747]=3, - [1748]=6, - [1749]=3, - [1750]=5, - [1751]=5, - [1752]=5, - [1753]=5, - [1754]=5, - [1755]=5, - [1756]=5, - [1757]=4, - [1758]=6, - [1759]=5, - [1760]=5, - [1761]=5, - [1762]=5, - [1763]=5, - [1764]=5, - [1765]=6, - [1766]=6, - [1767]=5, - [1768]=5, - [1769]=6, - [1770]=5, - [1771]=5, - [1772]=5, - [1773]=5, - [1774]=3, - [1775]=3, - [1776]=6, - [1777]=6, - [1778]=6, - [1779]=6, - [1780]=6, - [1781]=6, - [1782]=6, - [1783]=6, - [1784]=6, - [1785]=6, - [1786]=2, - [1787]=2, - [1788]=2, - [1789]=6, - [1790]=6, - [1791]=2, - [1792]=6, - [1793]=6, - [1794]=6, - [1795]=6, - [1796]=6, - [1797]=6, - [1798]=6, - [1799]=6, - [1800]=6, - [1801]=6, - [1802]=6, - [1803]=6, - [1804]=6, - [1805]=6, - [1808]=3, - [1809]=5, - [1810]=2, - [1811]=2, - [1812]=2, - [1813]=3, - [1814]=3, - [1815]=3, - [1816]=3, - [1817]=3, - [1818]=2, - [1819]=2, - [1820]=2, - [1821]=2, - [1822]=3, - [1823]=2, - [1824]=2, - [1825]=2, - [1826]=2, - [1827]=2, - [1828]=2, - [1829]=2, - [1830]=2, - [1831]=2, - [1832]=3, - [1833]=2, - [1834]=3, - [1835]=2, - [1836]=3, - [1837]=2, - [1838]=2, - [1839]=3, - [1840]=5, - [1841]=5, - [1842]=5, - [1843]=5, - [1844]=5, - [1845]=5, - [1846]=5, - [1847]=5, - [1848]=5, - [1849]=5, - [1850]=5, - [1851]=5, - [1852]=5, - [1853]=5, - [1854]=5, - [1855]=5, - [1856]=5, - [1857]=5, - [1858]=5, - [1859]=5, - [1860]=5, - [1861]=5, - [1862]=5, - [1863]=5, - [1864]=5, - [1865]=5, - [1866]=5, - [1869]=3, - [1870]=2, - [1871]=2, - [1872]=2, - [1873]=2, - [1874]=2, - [1875]=2, - [1876]=2, - [1877]=2, - [1878]=2, - [1879]=2, - [1880]=2, - [1881]=3, - [1882]=3, - [1883]=3, - [1884]=2, - [1885]=2, - [1886]=2, - [1887]=2, - [1888]=2, - [1889]=2, - [1890]=2, - [1891]=2, - [1892]=2, - [1893]=2, - [1894]=2, - [1895]=2, - [1896]=2, - [1897]=2, - [1898]=2, - [1899]=3, - [1900]=3, - [1901]=2, - [1902]=2, - [1903]=2, - [1904]=2, - [1905]=3, - [1906]=2, - [1907]=3, - [1908]=3, - [1909]=2, - [1910]=2, - [1911]=2, - [1912]=3, - [1913]=3, - [1914]=2, - [1915]=2, - [1916]=2, - [1917]=2, - [1918]=2, - [1919]=2, - [1958]=5, - [1959]=5, - [1960]=5, - [1961]=5, - [1962]=5, - [1963]=5, - [1964]=5, - [1965]=5, - [1966]=5, - [1967]=5, - [1968]=5, - [1984]=6, - [1985]=6, - [1986]=6, - [1987]=6, - [1988]=6, - [1989]=6, - [1990]=6, - [1991]=6, - [1992]=6, - [1993]=6, - [1994]=2, - [1995]=2, - [1996]=2, - [1997]=2, - [1998]=2, - [1999]=2, - [2000]=2, - [2001]=2, - [2002]=2, - [2003]=2, - [2004]=2, - [2005]=2, - [2006]=2, - [2007]=2, - [2008]=2, - [2009]=2, - [2010]=2, - [2011]=2, - [2012]=2, - [2013]=2, - [2014]=2, - [2015]=2, - [2016]=2, - [2017]=2, - [2018]=2, - [2019]=2, - [2020]=2, - [2021]=2, - [2022]=2, - [2023]=2, - [2024]=2, - [2025]=2, - [2026]=2, - [2027]=5, - [2028]=5, - [2029]=5, - [2030]=5, - [2031]=5, - [2032]=5, - [2033]=5, - [2034]=5, - [2035]=5, - [2036]=6, - [2037]=6, - [2038]=6, - [2039]=6, - [2040]=6, - [2041]=6, - [2042]=2, - [2045]=5, - [2046]=6, - [2047]=6, - [2070]=5, - [2071]=5, - [2072]=5, - [2073]=5, - [2075]=5, - [2076]=5, - [2077]=5, - [2078]=5, - [2079]=5, - [2080]=5, - [2081]=5, - [2082]=5, - [2083]=5, - [2085]=5, - [2086]=5, - [2087]=5, - [2089]=5, - [2090]=5, - [2091]=5, - [2092]=5, - [2093]=5, - [2112]=3, - [2113]=2, - [2114]=2, - [2115]=2, - [2116]=2, - [2117]=2, - [2118]=3, - [2119]=3, - [2120]=2, - [2121]=3, - [2122]=2, - [2123]=2, - [2124]=2, - [2125]=2, - [2126]=2, - [2127]=2, - [2128]=2, - [2129]=2, - [2130]=2, - [2131]=2, - [2132]=3, - [2133]=2, - [2134]=4, - [2135]=4, - [2136]=4, - [2137]=5, - [2138]=5, - [2139]=5, - [2144]=2, - [2145]=4, - [2146]=2, - [2147]=2, - [2148]=2, - [2149]=2, - [2150]=4, - [2151]=3, - [2152]=2, - [2153]=3, - [2154]=3, - [2208]=2, - [2209]=2, - [2210]=2, - [2211]=2, - [2212]=2, - [2213]=2, - [2214]=2, - [2215]=2, - [2216]=2, - [2217]=2, - [2218]=3, - [2219]=3, - [2220]=3, - [2221]=4, - [2222]=3, - [2223]=2, - [2224]=2, - [2225]=3, - [2226]=3, - [2227]=2, - [2228]=2, - [2230]=2, - [2231]=2, - [2232]=2, - [2233]=3, - [2234]=2, - [2235]=2, - [2236]=2, - [2237]=2, - [2259]=5, - [2260]=5, - [2261]=5, - [2262]=5, - [2263]=5, - [2264]=5, - [2265]=5, - [2266]=5, - [2267]=5, - [2268]=5, - [2269]=5, - [2270]=5, - [2271]=5, - [2272]=5, - [2273]=5, - [2274]=4, - [2275]=5, - [2276]=5, - [2277]=5, - [2278]=5, - [2279]=5, - [2280]=5, - [2281]=5, - [2282]=5, - [2283]=5, - [2284]=5, - [2285]=5, - [2286]=5, - [2287]=5, - [2288]=5, - [2289]=5, - [2290]=5, - [2291]=5, - [2292]=5, - [2293]=5, - [2294]=5, - [2295]=5, - [2296]=5, - [2297]=5, - [2298]=5, - [2299]=5, - [2300]=5, - [2301]=5, - [2302]=5, - [2303]=5, - [2304]=5, - [2305]=5, - [2306]=5, - [2362]=5, - [2364]=5, - [2369]=5, - [2370]=5, - [2371]=5, - [2372]=5, - [2373]=5, - [2374]=5, - [2375]=5, - [2376]=5, - [2381]=5, - [2385]=5, - [2386]=5, - [2387]=5, - [2388]=5, - [2389]=5, - [2390]=5, - [2391]=5, - [2402]=5, - [2403]=5, - [2433]=5, - [2492]=5, - [2497]=5, - [2498]=5, - [2499]=5, - [2500]=5, - [2509]=5, - [2530]=5, - [2531]=5, - [2558]=5, - [2561]=5, - [2562]=5, - [2620]=5, - [2625]=5, - [2626]=5, - [2631]=5, - [2632]=5, - [2635]=5, - [2636]=5, - [2637]=5, - [2641]=5, - [2672]=5, - [2673]=5, - [2677]=5, - [2689]=5, - [2690]=5, - [2748]=5, - [2753]=5, - [2754]=5, - [2755]=5, - [2756]=5, - [2757]=5, - [2759]=5, - [2760]=5, - [2765]=5, - [2786]=5, - [2787]=5, - [2810]=5, - [2811]=5, - [2812]=5, - [2813]=5, - [2814]=5, - [2815]=5, - [2817]=5, - [2876]=5, - [2879]=5, - [2881]=5, - [2882]=5, - [2883]=5, - [2884]=5, - [2893]=5, - [2902]=5, - [2914]=5, - [2915]=5, - [2946]=5, - [3008]=5, - [3021]=5, - [3072]=5, - [3076]=5, - [3134]=5, - [3135]=5, - [3136]=5, - [3142]=5, - [3143]=5, - [3144]=5, - [3146]=5, - [3147]=5, - [3148]=5, - [3149]=5, - [3157]=5, - [3158]=5, - [3170]=5, - [3171]=5, - [3201]=5, - [3260]=5, - [3263]=5, - [3270]=5, - [3276]=5, - [3277]=5, - [3298]=5, - [3299]=5, - [3328]=5, - [3329]=5, - [3387]=5, - [3388]=5, - [3393]=5, - [3394]=5, - [3395]=5, - [3396]=5, - [3405]=5, - [3426]=5, - [3427]=5, - [3530]=5, - [3538]=5, - [3539]=5, - [3540]=5, - [3542]=5, - [3633]=5, - [3636]=5, - [3637]=5, - [3638]=5, - [3639]=5, - [3640]=5, - [3641]=5, - [3642]=5, - [3655]=5, - [3656]=5, - [3657]=5, - [3658]=5, - [3659]=5, - [3660]=5, - [3661]=5, - [3662]=5, - [3761]=5, - [3764]=5, - [3765]=5, - [3766]=5, - [3767]=5, - [3768]=5, - [3769]=5, - [3770]=5, - [3771]=5, - [3772]=5, - [3784]=5, - [3785]=5, - [3786]=5, - [3787]=5, - [3788]=5, - [3789]=5, - [3864]=5, - [3865]=5, - [3893]=5, - [3895]=5, - [3897]=5, - [3953]=5, - [3954]=5, - [3955]=5, - [3956]=5, - [3957]=5, - [3958]=5, - [3959]=5, - [3960]=5, - [3961]=5, - [3962]=5, - [3963]=5, - [3964]=5, - [3965]=5, - [3966]=5, - [3968]=5, - [3969]=5, - [3970]=5, - [3971]=5, - [3972]=5, - [3974]=5, - [3975]=5, - [3981]=5, - [3982]=5, - [3983]=5, - [3984]=5, - [3985]=5, - [3986]=5, - [3987]=5, - [3988]=5, - [3989]=5, - [3990]=5, - [3991]=5, - [3993]=5, - [3994]=5, - [3995]=5, - [3996]=5, - [3997]=5, - [3998]=5, - [3999]=5, - [4000]=5, - [4001]=5, - [4002]=5, - [4003]=5, - [4004]=5, - [4005]=5, - [4006]=5, - [4007]=5, - [4008]=5, - [4009]=5, - [4010]=5, - [4011]=5, - [4012]=5, - [4013]=5, - [4014]=5, - [4015]=5, - [4016]=5, - [4017]=5, - [4018]=5, - [4019]=5, - [4020]=5, - [4021]=5, - [4022]=5, - [4023]=5, - [4024]=5, - [4025]=5, - [4026]=5, - [4027]=5, - [4028]=5, - [4038]=5, - [4141]=5, - [4142]=5, - [4143]=5, - [4144]=5, - [4146]=5, - [4147]=5, - [4148]=5, - [4149]=5, - [4150]=5, - [4151]=5, - [4153]=5, - [4154]=5, - [4157]=5, - [4158]=5, - [4184]=5, - [4185]=5, - [4190]=5, - [4191]=5, - [4192]=5, - [4209]=5, - [4210]=5, - [4211]=5, - [4212]=5, - [4226]=5, - [4229]=5, - [4230]=5, - [4237]=5, - [4253]=5, - [4957]=5, - [4958]=5, - [4959]=5, - [5906]=5, - [5907]=5, - [5908]=5, - [5938]=5, - [5939]=5, - [5940]=5, - [5970]=5, - [5971]=5, - [6002]=5, - [6003]=5, - [6071]=5, - [6072]=5, - [6073]=5, - [6074]=5, - [6075]=5, - [6076]=5, - [6077]=5, - [6086]=5, - [6089]=5, - [6090]=5, - [6091]=5, - [6092]=5, - [6093]=5, - [6094]=5, - [6095]=5, - [6096]=5, - [6097]=5, - [6098]=5, - [6099]=5, - [6109]=5, - [6150]=4, - [6151]=2, - [6154]=2, - [6155]=5, - [6156]=5, - [6157]=5, - [6158]=4, - [6176]=2, - [6177]=2, - [6178]=2, - [6179]=2, - [6180]=2, - [6181]=2, - [6182]=2, - [6183]=2, - [6184]=2, - [6185]=2, - [6186]=2, - [6187]=2, - [6188]=2, - [6189]=2, - [6190]=2, - [6191]=2, - [6192]=2, - [6193]=2, - [6194]=2, - [6195]=2, - [6196]=2, - [6197]=2, - [6198]=2, - [6199]=2, - [6200]=2, - [6201]=2, - [6202]=2, - [6203]=2, - [6204]=2, - [6205]=2, - [6206]=2, - [6207]=2, - [6208]=2, - [6209]=2, - [6210]=2, - [6211]=2, - [6212]=2, - [6213]=2, - [6214]=2, - [6215]=2, - [6216]=2, - [6217]=2, - [6218]=2, - [6219]=2, - [6220]=2, - [6221]=2, - [6222]=2, - [6223]=2, - [6224]=2, - [6225]=2, - [6226]=2, - [6227]=2, - [6228]=2, - [6229]=2, - [6230]=2, - [6231]=2, - [6232]=2, - [6233]=2, - [6234]=2, - [6235]=2, - [6236]=2, - [6237]=2, - [6238]=2, - [6239]=2, - [6240]=2, - [6241]=2, - [6242]=2, - [6243]=2, - [6244]=2, - [6245]=2, - [6246]=2, - [6247]=2, - [6248]=2, - [6249]=2, - [6250]=2, - [6251]=2, - [6252]=2, - [6253]=2, - [6254]=2, - [6255]=2, - [6256]=2, - [6257]=2, - [6258]=2, - [6259]=2, - [6260]=2, - [6261]=2, - [6262]=2, - [6263]=2, - [6264]=2, - [6272]=4, - [6273]=4, - [6274]=4, - [6275]=4, - [6276]=4, - [6279]=2, - [6280]=2, - [6281]=2, - [6282]=2, - [6283]=2, - [6284]=2, - [6285]=2, - [6286]=2, - [6287]=2, - [6288]=2, - [6289]=2, - [6290]=2, - [6291]=2, - [6292]=2, - [6293]=2, - [6294]=2, - [6295]=2, - [6296]=2, - [6297]=2, - [6298]=2, - [6299]=2, - [6300]=2, - [6301]=2, - [6302]=2, - [6303]=2, - [6304]=2, - [6305]=2, - [6306]=2, - [6307]=2, - [6308]=2, - [6309]=2, - [6310]=2, - [6311]=2, - [6312]=2, - [6313]=5, - [6314]=2, - [6432]=5, - [6433]=5, - [6434]=5, - [6439]=5, - [6440]=5, - [6450]=5, - [6457]=5, - [6458]=5, - [6459]=5, - [6679]=5, - [6680]=5, - [6742]=5, - [6744]=5, - [6745]=5, - [6746]=5, - [6747]=5, - [6748]=5, - [6749]=5, - [6750]=5, - [6752]=5, - [6754]=5, - [6757]=5, - [6758]=5, - [6759]=5, - [6760]=5, - [6761]=5, - [6762]=5, - [6763]=5, - [6764]=5, - [6771]=5, - [6772]=5, - [6773]=5, - [6774]=5, - [6775]=5, - [6776]=5, - [6777]=5, - [6778]=5, - [6779]=5, - [6780]=5, - [6783]=5, - [6832]=5, - [6833]=5, - [6834]=5, - [6835]=5, - [6836]=5, - [6837]=5, - [6838]=5, - [6839]=5, - [6840]=5, - [6841]=5, - [6842]=5, - [6843]=5, - [6844]=5, - [6845]=5, - [6912]=5, - [6913]=5, - [6914]=5, - [6915]=5, - [6964]=5, - [6966]=5, - [6967]=5, - [6968]=5, - [6969]=5, - [6970]=5, - [6972]=5, - [6978]=5, - [7019]=5, - [7020]=5, - [7021]=5, - [7022]=5, - [7023]=5, - [7024]=5, - [7025]=5, - [7026]=5, - [7027]=5, - [7040]=5, - [7041]=5, - [7074]=5, - [7075]=5, - [7076]=5, - [7077]=5, - [7080]=5, - [7081]=5, - [7083]=5, - [7142]=5, - [7144]=5, - [7145]=5, - [7149]=5, - [7151]=5, - [7152]=5, - [7153]=5, - [7212]=5, - [7213]=5, - [7214]=5, - [7215]=5, - [7216]=5, - [7217]=5, - [7218]=5, - [7219]=5, - [7222]=5, - [7223]=5, - [7376]=5, - [7377]=5, - [7378]=5, - [7380]=5, - [7381]=5, - [7382]=5, - [7383]=5, - [7384]=5, - [7385]=5, - [7386]=5, - [7387]=5, - [7388]=5, - [7389]=5, - [7390]=5, - [7391]=5, - [7392]=5, - [7394]=5, - [7395]=5, - [7396]=5, - [7397]=5, - [7398]=5, - [7399]=5, - [7400]=5, - [7405]=5, - [7412]=5, - [7416]=5, - [7417]=5, - [7616]=5, - [7617]=5, - [7618]=5, - [7619]=5, - [7620]=5, - [7621]=5, - [7622]=5, - [7623]=5, - [7624]=5, - [7625]=5, - [7626]=5, - [7627]=5, - [7628]=5, - [7629]=5, - [7630]=5, - [7631]=5, - [7632]=5, - [7633]=5, - [7634]=5, - [7635]=5, - [7636]=5, - [7637]=5, - [7638]=5, - [7639]=5, - [7640]=5, - [7641]=5, - [7642]=5, - [7643]=5, - [7644]=5, - [7645]=5, - [7646]=5, - [7647]=5, - [7648]=5, - [7649]=5, - [7650]=5, - [7651]=5, - [7652]=5, - [7653]=5, - [7654]=5, - [7655]=5, - [7656]=5, - [7657]=5, - [7658]=5, - [7659]=5, - [7660]=5, - [7661]=5, - [7662]=5, - [7663]=5, - [7664]=5, - [7665]=5, - [7666]=5, - [7667]=5, - [7668]=5, - [7669]=5, - [7670]=5, - [7671]=5, - [7672]=5, - [7673]=5, - [7675]=5, - [7676]=5, - [7677]=5, - [7678]=5, - [7679]=5, - [8204]=4, - [8205]=2, - [8239]=4, - [8294]=4, - [8295]=4, - [8296]=4, - [8297]=4, - [8400]=5, - [8401]=5, - [8402]=5, - [8403]=5, - [8404]=5, - [8405]=5, - [8406]=5, - [8407]=5, - [8408]=5, - [8409]=5, - [8410]=5, - [8411]=5, - [8412]=5, - [8417]=5, - [8421]=5, - [8422]=5, - [8423]=5, - [8424]=5, - [8425]=5, - [8426]=5, - [8427]=5, - [8428]=5, - [8429]=5, - [8430]=5, - [8431]=5, - [8432]=5, - [11503]=5, - [11504]=5, - [11505]=5, - [11647]=5, - [11744]=5, - [11745]=5, - [11746]=5, - [11747]=5, - [11748]=5, - [11749]=5, - [11750]=5, - [11751]=5, - [11752]=5, - [11753]=5, - [11754]=5, - [11755]=5, - [11756]=5, - [11757]=5, - [11758]=5, - [11759]=5, - [11760]=5, - [11761]=5, - [11762]=5, - [11763]=5, - [11764]=5, - [11765]=5, - [11766]=5, - [11767]=5, - [11768]=5, - [11769]=5, - [11770]=5, - [11771]=5, - [11772]=5, - [11773]=5, - [11774]=5, - [11775]=5, - [12330]=5, - [12331]=5, - [12332]=5, - [12333]=5, - [12334]=5, - [12335]=5, - [12441]=5, - [12442]=5, - [42607]=5, - [42612]=5, - [42613]=5, - [42614]=5, - [42615]=5, - [42616]=5, - [42617]=5, - [42618]=5, - [42619]=5, - [42620]=5, - [42621]=5, - [42654]=5, - [42655]=5, - [42736]=5, - [42737]=5, - [43014]=5, - [43019]=5, - [43045]=5, - [43046]=5, - [43072]=2, - [43073]=2, - [43074]=2, - [43075]=2, - [43076]=2, - [43077]=2, - [43078]=2, - [43079]=2, - [43080]=2, - [43081]=2, - [43082]=2, - [43083]=2, - [43084]=2, - [43085]=2, - [43086]=2, - [43087]=2, - [43088]=2, - [43089]=2, - [43090]=2, - [43091]=2, - [43092]=2, - [43093]=2, - [43094]=2, - [43095]=2, - [43096]=2, - [43097]=2, - [43098]=2, - [43099]=2, - [43100]=2, - [43101]=2, - [43102]=2, - [43103]=2, - [43104]=2, - [43105]=2, - [43106]=2, - [43107]=2, - [43108]=2, - [43109]=2, - [43110]=2, - [43111]=2, - [43112]=2, - [43113]=2, - [43114]=2, - [43115]=2, - [43116]=2, - [43117]=2, - [43118]=2, - [43119]=2, - [43120]=2, - [43121]=2, - [43122]=1, - [43123]=4, - [43204]=5, - [43205]=5, - [43232]=5, - [43233]=5, - [43234]=5, - [43235]=5, - [43236]=5, - [43237]=5, - [43238]=5, - [43239]=5, - [43240]=5, - [43241]=5, - [43242]=5, - [43243]=5, - [43244]=5, - [43245]=5, - [43246]=5, - [43247]=5, - [43248]=5, - [43249]=5, - [43263]=5, - [43302]=5, - [43303]=5, - [43304]=5, - [43305]=5, - [43306]=5, - [43307]=5, - [43308]=5, - [43309]=5, - [43335]=5, - [43336]=5, - [43337]=5, - [43338]=5, - [43339]=5, - [43340]=5, - [43341]=5, - [43342]=5, - [43343]=5, - [43344]=5, - [43345]=5, - [43392]=5, - [43393]=5, - [43394]=5, - [43443]=5, - [43446]=5, - [43447]=5, - [43448]=5, - [43449]=5, - [43452]=5, - [43493]=5, - [43561]=5, - [43562]=5, - [43563]=5, - [43564]=5, - [43565]=5, - [43566]=5, - [43569]=5, - [43570]=5, - [43573]=5, - [43574]=5, - [43587]=5, - [43596]=5, - [43644]=5, - [43696]=5, - [43698]=5, - [43699]=5, - [43700]=5, - [43703]=5, - [43704]=5, - [43710]=5, - [43711]=5, - [43713]=5, - [43756]=5, - [43757]=5, - [43766]=5, - [44005]=5, - [44008]=5, - [44013]=5, - [64286]=5, - [65056]=5, - [65057]=5, - [65058]=5, - [65059]=5, - [65060]=5, - [65061]=5, - [65062]=5, - [65063]=5, - [65064]=5, - [65065]=5, - [65066]=5, - [65067]=5, - [65068]=5, - [65069]=5, - [65070]=5, - [65071]=5, - [66045]=5, - [66272]=5, - [66422]=5, - [66423]=5, - [66424]=5, - [66425]=5, - [66426]=5, - [68097]=5, - [68098]=5, - [68099]=5, - [68101]=5, - [68102]=5, - [68108]=5, - [68109]=5, - [68110]=5, - [68111]=5, - [68152]=5, - [68153]=5, - [68154]=5, - [68159]=5, - [68288]=2, - [68289]=2, - [68290]=2, - [68291]=2, - [68292]=2, - [68293]=3, - [68294]=4, - [68295]=3, - [68296]=4, - [68297]=3, - [68298]=3, - [68299]=4, - [68300]=4, - [68301]=1, - [68302]=3, - [68303]=3, - [68304]=3, - [68305]=3, - [68306]=3, - [68307]=2, - [68308]=2, - [68309]=2, - [68310]=2, - [68311]=1, - [68312]=2, - [68313]=2, - [68314]=2, - [68315]=2, - [68316]=2, - [68317]=3, - [68318]=2, - [68319]=2, - [68320]=2, - [68321]=3, - [68322]=4, - [68323]=4, - [68324]=3, - [68325]=5, - [68326]=5, - [68331]=2, - [68332]=2, - [68333]=2, - [68334]=2, - [68335]=3, - [68480]=2, - [68481]=3, - [68482]=2, - [68483]=3, - [68484]=3, - [68485]=3, - [68486]=2, - [68487]=2, - [68488]=2, - [68489]=3, - [68490]=2, - [68491]=2, - [68492]=3, - [68493]=2, - [68494]=3, - [68495]=3, - [68496]=2, - [68497]=3, - [68521]=3, - [68522]=3, - [68523]=3, - [68524]=3, - [68525]=2, - [68526]=2, - [68527]=4, - [68864]=1, - [68865]=2, - [68866]=2, - [68867]=2, - [68868]=2, - [68869]=2, - [68870]=2, - [68871]=2, - [68872]=2, - [68873]=2, - [68874]=2, - [68875]=2, - [68876]=2, - [68877]=2, - [68878]=2, - [68879]=2, - [68880]=2, - [68881]=2, - [68882]=2, - [68883]=2, - [68884]=2, - [68885]=2, - [68886]=2, - [68887]=2, - [68888]=2, - [68889]=2, - [68890]=2, - [68891]=2, - [68892]=2, - [68893]=2, - [68894]=2, - [68895]=2, - [68896]=2, - [68897]=2, - [68898]=3, - [68899]=2, - [68900]=5, - [68901]=5, - [68902]=5, - [68903]=5, - [69424]=2, - [69425]=2, - [69426]=2, - [69427]=3, - [69428]=2, - [69429]=2, - [69430]=2, - [69431]=2, - [69432]=2, - [69433]=2, - [69434]=2, - [69435]=2, - [69436]=2, - [69437]=2, - [69438]=2, - [69439]=2, - [69440]=2, - [69441]=2, - [69442]=2, - [69443]=2, - [69444]=2, - [69445]=4, - [69446]=5, - [69447]=5, - [69448]=5, - [69449]=5, - [69450]=5, - [69451]=5, - [69452]=5, - [69453]=5, - [69454]=5, - [69455]=5, - [69456]=5, - [69457]=2, - [69458]=2, - [69459]=2, - [69460]=3, - [69633]=5, - [69688]=5, - [69689]=5, - [69690]=5, - [69691]=5, - [69692]=5, - [69693]=5, - [69694]=5, - [69695]=5, - [69696]=5, - [69697]=5, - [69698]=5, - [69699]=5, - [69700]=5, - [69701]=5, - [69702]=5, - [69759]=5, - [69760]=5, - [69761]=5, - [69811]=5, - [69812]=5, - [69813]=5, - [69814]=5, - [69817]=5, - [69818]=5, - [69821]=4, - [69837]=4, - [69888]=5, - [69889]=5, - [69890]=5, - [69927]=5, - [69928]=5, - [69929]=5, - [69930]=5, - [69931]=5, - [69933]=5, - [69934]=5, - [69935]=5, - [69936]=5, - [69937]=5, - [69938]=5, - [69939]=5, - [69940]=5, - [70003]=5, - [70016]=5, - [70017]=5, - [70070]=5, - [70071]=5, - [70072]=5, - [70073]=5, - [70074]=5, - [70075]=5, - [70076]=5, - [70077]=5, - [70078]=5, - [70090]=5, - [70091]=5, - [70092]=5, - [70191]=5, - [70192]=5, - [70193]=5, - [70196]=5, - [70198]=5, - [70199]=5, - [70206]=5, - [70367]=5, - [70371]=5, - [70372]=5, - [70373]=5, - [70374]=5, - [70375]=5, - [70376]=5, - [70377]=5, - [70378]=5, - [70400]=5, - [70401]=5, - [70459]=5, - [70460]=5, - [70464]=5, - [70502]=5, - [70503]=5, - [70504]=5, - [70505]=5, - [70506]=5, - [70507]=5, - [70508]=5, - [70512]=5, - [70513]=5, - [70514]=5, - [70515]=5, - [70516]=5, - [70712]=5, - [70713]=5, - [70714]=5, - [70715]=5, - [70716]=5, - [70717]=5, - [70718]=5, - [70719]=5, - [70722]=5, - [70723]=5, - [70724]=5, - [70726]=5, - [70750]=5, - [70835]=5, - [70836]=5, - [70837]=5, - [70838]=5, - [70839]=5, - [70840]=5, - [70842]=5, - [70847]=5, - [70848]=5, - [70850]=5, - [70851]=5, - [71090]=5, - [71091]=5, - [71092]=5, - [71093]=5, - [71100]=5, - [71101]=5, - [71103]=5, - [71104]=5, - [71132]=5, - [71133]=5, - [71219]=5, - [71220]=5, - [71221]=5, - [71222]=5, - [71223]=5, - [71224]=5, - [71225]=5, - [71226]=5, - [71229]=5, - [71231]=5, - [71232]=5, - [71339]=5, - [71341]=5, - [71344]=5, - [71345]=5, - [71346]=5, - [71347]=5, - [71348]=5, - [71349]=5, - [71351]=5, - [71453]=5, - [71454]=5, - [71455]=5, - [71458]=5, - [71459]=5, - [71460]=5, - [71461]=5, - [71463]=5, - [71464]=5, - [71465]=5, - [71466]=5, - [71467]=5, - [71727]=5, - [71728]=5, - [71729]=5, - [71730]=5, - [71731]=5, - [71732]=5, - [71733]=5, - [71734]=5, - [71735]=5, - [71737]=5, - [71738]=5, - [72148]=5, - [72149]=5, - [72150]=5, - [72151]=5, - [72154]=5, - [72155]=5, - [72160]=5, - [72193]=5, - [72194]=5, - [72195]=5, - [72196]=5, - [72197]=5, - [72198]=5, - [72201]=5, - [72202]=5, - [72243]=5, - [72244]=5, - [72245]=5, - [72246]=5, - [72247]=5, - [72248]=5, - [72251]=5, - [72252]=5, - [72253]=5, - [72254]=5, - [72263]=5, - [72273]=5, - [72274]=5, - [72275]=5, - [72276]=5, - [72277]=5, - [72278]=5, - [72281]=5, - [72282]=5, - [72283]=5, - [72330]=5, - [72331]=5, - [72332]=5, - [72333]=5, - [72334]=5, - [72335]=5, - [72336]=5, - [72337]=5, - [72338]=5, - [72339]=5, - [72340]=5, - [72341]=5, - [72342]=5, - [72344]=5, - [72345]=5, - [72752]=5, - [72753]=5, - [72754]=5, - [72755]=5, - [72756]=5, - [72757]=5, - [72758]=5, - [72760]=5, - [72761]=5, - [72762]=5, - [72763]=5, - [72764]=5, - [72765]=5, - [72767]=5, - [72850]=5, - [72851]=5, - [72852]=5, - [72853]=5, - [72854]=5, - [72855]=5, - [72856]=5, - [72857]=5, - [72858]=5, - [72859]=5, - [72860]=5, - [72861]=5, - [72862]=5, - [72863]=5, - [72864]=5, - [72865]=5, - [72866]=5, - [72867]=5, - [72868]=5, - [72869]=5, - [72870]=5, - [72871]=5, - [72874]=5, - [72875]=5, - [72876]=5, - [72877]=5, - [72878]=5, - [72879]=5, - [72880]=5, - [72882]=5, - [72883]=5, - [72885]=5, - [72886]=5, - [73009]=5, - [73010]=5, - [73011]=5, - [73012]=5, - [73013]=5, - [73014]=5, - [73018]=5, - [73020]=5, - [73021]=5, - [73023]=5, - [73024]=5, - [73025]=5, - [73026]=5, - [73027]=5, - [73028]=5, - [73029]=5, - [73031]=5, - [73104]=5, - [73105]=5, - [73109]=5, - [73111]=5, - [73459]=5, - [73460]=5, - [92912]=5, - [92913]=5, - [92914]=5, - [92915]=5, - [92916]=5, - [92976]=5, - [92977]=5, - [92978]=5, - [92979]=5, - [92980]=5, - [92981]=5, - [92982]=5, - [94031]=5, - [94095]=5, - [94096]=5, - [94097]=5, - [94098]=5, - [113821]=5, - [113822]=5, - [119143]=5, - [119144]=5, - [119145]=5, - [119163]=5, - [119164]=5, - [119165]=5, - [119166]=5, - [119167]=5, - [119168]=5, - [119169]=5, - [119170]=5, - [119173]=5, - [119174]=5, - [119175]=5, - [119176]=5, - [119177]=5, - [119178]=5, - [119179]=5, - [119210]=5, - [119211]=5, - [119212]=5, - [119213]=5, - [119362]=5, - [119363]=5, - [119364]=5, - [121344]=5, - [121345]=5, - [121346]=5, - [121347]=5, - [121348]=5, - [121349]=5, - [121350]=5, - [121351]=5, - [121352]=5, - [121353]=5, - [121354]=5, - [121355]=5, - [121356]=5, - [121357]=5, - [121358]=5, - [121359]=5, - [121360]=5, - [121361]=5, - [121362]=5, - [121363]=5, - [121364]=5, - [121365]=5, - [121366]=5, - [121367]=5, - [121368]=5, - [121369]=5, - [121370]=5, - [121371]=5, - [121372]=5, - [121373]=5, - [121374]=5, - [121375]=5, - [121376]=5, - [121377]=5, - [121378]=5, - [121379]=5, - [121380]=5, - [121381]=5, - [121382]=5, - [121383]=5, - [121384]=5, - [121385]=5, - [121386]=5, - [121387]=5, - [121388]=5, - [121389]=5, - [121390]=5, - [121391]=5, - [121392]=5, - [121393]=5, - [121394]=5, - [121395]=5, - [121396]=5, - [121397]=5, - [121398]=5, - [121403]=5, - [121404]=5, - [121405]=5, - [121406]=5, - [121407]=5, - [121408]=5, - [121409]=5, - [121410]=5, - [121411]=5, - [121412]=5, - [121413]=5, - [121414]=5, - [121415]=5, - [121416]=5, - [121417]=5, - [121418]=5, - [121419]=5, - [121420]=5, - [121421]=5, - [121422]=5, - [121423]=5, - [121424]=5, - [121425]=5, - [121426]=5, - [121427]=5, - [121428]=5, - [121429]=5, - [121430]=5, - [121431]=5, - [121432]=5, - [121433]=5, - [121434]=5, - [121435]=5, - [121436]=5, - [121437]=5, - [121438]=5, - [121439]=5, - [121440]=5, - [121441]=5, - [121442]=5, - [121443]=5, - [121444]=5, - [121445]=5, - [121446]=5, - [121447]=5, - [121448]=5, - [121449]=5, - [121450]=5, - [121451]=5, - [121452]=5, - [121461]=5, - [121476]=5, - [121499]=5, - [121500]=5, - [121501]=5, - [121502]=5, - [121503]=5, - [121505]=5, - [121506]=5, - [121507]=5, - [121508]=5, - [121509]=5, - [121510]=5, - [121511]=5, - [121512]=5, - [121513]=5, - [121514]=5, - [121515]=5, - [121516]=5, - [121517]=5, - [121518]=5, - [121519]=5, - [122880]=5, - [122881]=5, - [122882]=5, - [122883]=5, - [122884]=5, - [122885]=5, - [122886]=5, - [122888]=5, - [122889]=5, - [122890]=5, - [122891]=5, - [122892]=5, - [122893]=5, - [122894]=5, - [122895]=5, - [122896]=5, - [122897]=5, - [122898]=5, - [122899]=5, - [122900]=5, - [122901]=5, - [122902]=5, - [122903]=5, - [122904]=5, - [122907]=5, - [122908]=5, - [122909]=5, - [122910]=5, - [122911]=5, - [122912]=5, - [122913]=5, - [122915]=5, - [122916]=5, - [122918]=5, - [122919]=5, - [122920]=5, - [122921]=5, - [122922]=5, - [123184]=5, - [123185]=5, - [123186]=5, - [123187]=5, - [123188]=5, - [123189]=5, - [123190]=5, - [123628]=5, - [123629]=5, - [123630]=5, - [123631]=5, - [125136]=5, - [125137]=5, - [125138]=5, - [125139]=5, - [125140]=5, - [125141]=5, - [125142]=5, - [125184]=2, - [125185]=2, - [125186]=2, - [125187]=2, - [125188]=2, - [125189]=2, - [125190]=2, - [125191]=2, - [125192]=2, - [125193]=2, - [125194]=2, - [125195]=2, - [125196]=2, - [125197]=2, - [125198]=2, - [125199]=2, - [125200]=2, - [125201]=2, - [125202]=2, - [125203]=2, - [125204]=2, - [125205]=2, - [125206]=2, - [125207]=2, - [125208]=2, - [125209]=2, - [125210]=2, - [125211]=2, - [125212]=2, - [125213]=2, - [125214]=2, - [125215]=2, - [125216]=2, - [125217]=2, - [125218]=2, - [125219]=2, - [125220]=2, - [125221]=2, - [125222]=2, - [125223]=2, - [125224]=2, - [125225]=2, - [125226]=2, - [125227]=2, - [125228]=2, - [125229]=2, - [125230]=2, - [125231]=2, - [125232]=2, - [125233]=2, - [125234]=2, - [125235]=2, - [125236]=2, - [125237]=2, - [125238]=2, - [125239]=2, - [125240]=2, - [125241]=2, - [125242]=2, - [125243]=2, - [125244]=2, - [125245]=2, - [125246]=2, - [125247]=2, - [125248]=2, - [125249]=2, - [125250]=2, - [125251]=2, - [125252]=5, - [125253]=5, - [125254]=5, - [125255]=5, - [125256]=5, - [125257]=5, - [125258]=5, - [1042752]=5, -} -characters.indicgroups={ - ["above_mark"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2362]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2385]=true, - [2387]=true, - [2388]=true, - [2389]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2690]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2879]=true, - [3008]=true, - [3021]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3142]=true, - [3143]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3149]=true, - [3263]=true, - [3270]=true, - [3406]=true, - [4141]=true, - [4142]=true, - [4146]=true, - [4147]=true, - [4148]=true, - [4149]=true, - [4150]=true, - [4154]=true, - [4209]=true, - [4210]=true, - [4211]=true, - [4212]=true, - [4229]=true, - [4230]=true, - [4253]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43248]=true, - [43249]=true, - [43493]=true, - [43644]=true, - }, - ["after_half"]={}, - ["after_main"]={ - [2864]=true, - [2879]=true, - [2902]=true, - [3376]=true, - }, - ["after_postscript"]={ - [2433]=true, - [2494]=true, - [2496]=true, - [2519]=true, - [2561]=true, - [2562]=true, - [2622]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2672]=true, - [2673]=true, - [2735]=true, - [2750]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2786]=true, - [2787]=true, - [2878]=true, - [2880]=true, - [2903]=true, - [2992]=true, - [3006]=true, - [3007]=true, - [3009]=true, - [3010]=true, - [3031]=true, - [3120]=true, - [3248]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3415]=true, - }, - ["after_subscript"]={ - [2366]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2402]=true, - [2403]=true, - [2480]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2530]=true, - [2531]=true, - [2544]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [3008]=true, - [3139]=true, - [3140]=true, - [3267]=true, - [3268]=true, - [3285]=true, - [3286]=true, - }, - ["anudatta"]={ - [2386]=true, - }, - ["before_half"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2503]=true, - [2504]=true, - [2623]=true, - [2751]=true, - [2887]=true, - }, - ["before_main"]={ - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, - }, - ["before_postscript"]={ - [2352]=true, - [2736]=true, - }, - ["before_subscript"]={ - [2608]=true, - [2817]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3142]=true, - [3143]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3157]=true, - [3158]=true, - [3262]=true, - [3263]=true, - [3265]=true, - [3266]=true, - [3270]=true, - [3276]=true, - [3298]=true, - [3299]=true, - }, - ["below_mark"]={ - [2364]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2381]=true, - [2386]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2492]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2509]=true, - [2620]=true, - [2625]=true, - [2626]=true, - [2637]=true, - [2748]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2765]=true, - [2876]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2893]=true, - [2914]=true, - [2915]=true, - [3009]=true, - [3010]=true, - [3170]=true, - [3171]=true, - [3260]=true, - [3286]=true, - [3298]=true, - [3299]=true, - [3426]=true, - [3427]=true, - [4143]=true, - [4144]=true, - [4151]=true, - [4153]=true, - [4157]=true, - [4158]=true, - [4184]=true, - [4185]=true, - [4190]=true, - [4191]=true, - [4192]=true, - [4226]=true, - [4237]=true, - }, - ["consonant"]={ - [2325]=true, - [2326]=true, - [2327]=true, - [2328]=true, - [2329]=true, - [2330]=true, - [2331]=true, - [2332]=true, - [2333]=true, - [2334]=true, - [2335]=true, - [2336]=true, - [2337]=true, - [2338]=true, - [2339]=true, - [2340]=true, - [2341]=true, - [2342]=true, - [2343]=true, - [2344]=true, - [2345]=true, - [2346]=true, - [2347]=true, - [2348]=true, - [2349]=true, - [2350]=true, - [2351]=true, - [2352]=true, - [2353]=true, - [2354]=true, - [2355]=true, - [2356]=true, - [2357]=true, - [2358]=true, - [2359]=true, - [2360]=true, - [2361]=true, - [2392]=true, - [2393]=true, - [2394]=true, - [2395]=true, - [2396]=true, - [2397]=true, - [2398]=true, - [2399]=true, - [2424]=true, - [2425]=true, - [2426]=true, - [2453]=true, - [2454]=true, - [2455]=true, - [2456]=true, - [2457]=true, - [2458]=true, - [2459]=true, - [2460]=true, - [2461]=true, - [2462]=true, - [2463]=true, - [2464]=true, - [2465]=true, - [2466]=true, - [2467]=true, - [2468]=true, - [2469]=true, - [2470]=true, - [2471]=true, - [2472]=true, - [2474]=true, - [2475]=true, - [2476]=true, - [2477]=true, - [2478]=true, - [2479]=true, - [2480]=true, - [2482]=true, - [2486]=true, - [2487]=true, - [2488]=true, - [2489]=true, - [2510]=true, - [2524]=true, - [2525]=true, - [2527]=true, - [2581]=true, - [2582]=true, - [2583]=true, - [2584]=true, - [2585]=true, - [2586]=true, - [2587]=true, - [2588]=true, - [2589]=true, - [2590]=true, - [2591]=true, - [2592]=true, - [2593]=true, - [2594]=true, - [2595]=true, - [2596]=true, - [2597]=true, - [2598]=true, - [2599]=true, - [2600]=true, - [2602]=true, - [2603]=true, - [2604]=true, - [2605]=true, - [2606]=true, - [2607]=true, - [2608]=true, - [2610]=true, - [2611]=true, - [2613]=true, - [2614]=true, - [2616]=true, - [2617]=true, - [2649]=true, - [2650]=true, - [2651]=true, - [2652]=true, - [2654]=true, - [2709]=true, - [2710]=true, - [2711]=true, - [2712]=true, - [2713]=true, - [2714]=true, - [2715]=true, - [2716]=true, - [2717]=true, - [2718]=true, - [2719]=true, - [2720]=true, - [2721]=true, - [2722]=true, - [2723]=true, - [2724]=true, - [2725]=true, - [2726]=true, - [2727]=true, - [2728]=true, - [2730]=true, - [2731]=true, - [2732]=true, - [2733]=true, - [2734]=true, - [2735]=true, - [2736]=true, - [2738]=true, - [2739]=true, - [2741]=true, - [2742]=true, - [2743]=true, - [2744]=true, - [2745]=true, - [2837]=true, - [2838]=true, - [2839]=true, - [2840]=true, - [2841]=true, - [2842]=true, - [2843]=true, - [2844]=true, - [2845]=true, - [2846]=true, - [2847]=true, - [2848]=true, - [2849]=true, - [2850]=true, - [2851]=true, - [2852]=true, - [2853]=true, - [2854]=true, - [2855]=true, - [2856]=true, - [2858]=true, - [2859]=true, - [2860]=true, - [2861]=true, - [2862]=true, - [2863]=true, - [2864]=true, - [2866]=true, - [2867]=true, - [2869]=true, - [2870]=true, - [2871]=true, - [2872]=true, - [2873]=true, - [2908]=true, - [2909]=true, - [2929]=true, - [2965]=true, - [2969]=true, - [2970]=true, - [2972]=true, - [2974]=true, - [2975]=true, - [2979]=true, - [2980]=true, - [2984]=true, - [2985]=true, - [2986]=true, - [2990]=true, - [2991]=true, - [2992]=true, - [2993]=true, - [2994]=true, - [2995]=true, - [2996]=true, - [2997]=true, - [2998]=true, - [2999]=true, - [3000]=true, - [3001]=true, - [3093]=true, - [3094]=true, - [3095]=true, - [3096]=true, - [3097]=true, - [3098]=true, - [3099]=true, - [3100]=true, - [3101]=true, - [3102]=true, - [3103]=true, - [3104]=true, - [3105]=true, - [3106]=true, - [3107]=true, - [3108]=true, - [3109]=true, - [3110]=true, - [3111]=true, - [3112]=true, - [3114]=true, - [3115]=true, - [3116]=true, - [3117]=true, - [3118]=true, - [3119]=true, - [3120]=true, - [3121]=true, - [3122]=true, - [3123]=true, - [3124]=true, - [3125]=true, - [3126]=true, - [3127]=true, - [3128]=true, - [3129]=true, - [3133]=true, - [3221]=true, - [3222]=true, - [3223]=true, - [3224]=true, - [3225]=true, - [3226]=true, - [3227]=true, - [3228]=true, - [3229]=true, - [3230]=true, - [3231]=true, - [3232]=true, - [3233]=true, - [3234]=true, - [3235]=true, - [3236]=true, - [3237]=true, - [3238]=true, - [3239]=true, - [3240]=true, - [3242]=true, - [3243]=true, - [3244]=true, - [3245]=true, - [3246]=true, - [3247]=true, - [3248]=true, - [3249]=true, - [3250]=true, - [3251]=true, - [3253]=true, - [3254]=true, - [3255]=true, - [3256]=true, - [3257]=true, - [3294]=true, - [3349]=true, - [3350]=true, - [3351]=true, - [3352]=true, - [3353]=true, - [3354]=true, - [3355]=true, - [3356]=true, - [3357]=true, - [3358]=true, - [3359]=true, - [3360]=true, - [3361]=true, - [3362]=true, - [3363]=true, - [3364]=true, - [3365]=true, - [3366]=true, - [3367]=true, - [3368]=true, - [3369]=true, - [3370]=true, - [3371]=true, - [3372]=true, - [3373]=true, - [3374]=true, - [3375]=true, - [3376]=true, - [3377]=true, - [3378]=true, - [3379]=true, - [3380]=true, - [3381]=true, - [3382]=true, - [3383]=true, - [3384]=true, - [3385]=true, - [3386]=true, - [4096]=true, - [4097]=true, - [4098]=true, - [4099]=true, - [4100]=true, - [4101]=true, - [4102]=true, - [4103]=true, - [4104]=true, - [4105]=true, - [4106]=true, - [4107]=true, - [4108]=true, - [4109]=true, - [4110]=true, - [4111]=true, - [4112]=true, - [4113]=true, - [4114]=true, - [4115]=true, - [4116]=true, - [4117]=true, - [4118]=true, - [4119]=true, - [4120]=true, - [4121]=true, - [4122]=true, - [4123]=true, - [4124]=true, - [4125]=true, - [4126]=true, - [4127]=true, - [4128]=true, - [4155]=true, - [4156]=true, - [4157]=true, - [4158]=true, - [4159]=true, - [4176]=true, - [4177]=true, - [4186]=true, - [4187]=true, - [4188]=true, - [4189]=true, - [4190]=true, - [4191]=true, - [4192]=true, - [4193]=true, - [4197]=true, - [4198]=true, - [4206]=true, - [4207]=true, - [4208]=true, - [4213]=true, - [4214]=true, - [4215]=true, - [4216]=true, - [4217]=true, - [4218]=true, - [4219]=true, - [4220]=true, - [4221]=true, - [4222]=true, - [4223]=true, - [4224]=true, - [4225]=true, - [4226]=true, - [4238]=true, - [43488]=true, - [43489]=true, - [43490]=true, - [43491]=true, - [43492]=true, - [43495]=true, - [43496]=true, - [43497]=true, - [43498]=true, - [43499]=true, - [43500]=true, - [43501]=true, - [43502]=true, - [43503]=true, - [43514]=true, - [43515]=true, - [43516]=true, - [43517]=true, - [43518]=true, - [43616]=true, - [43617]=true, - [43618]=true, - [43619]=true, - [43620]=true, - [43621]=true, - [43622]=true, - [43623]=true, - [43624]=true, - [43625]=true, - [43626]=true, - [43628]=true, - [43629]=true, - [43630]=true, - [43631]=true, - [43633]=true, - [43634]=true, - [43635]=true, - [43636]=true, - [43637]=true, - [43638]=true, - [43642]=true, - [43646]=true, - [43647]=true, - }, - ["dependent_vowel"]={ - [2362]=true, - [2363]=true, - [2366]=true, - [2367]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2382]=true, - [2383]=true, - [2389]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2494]=true, - [2495]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2503]=true, - [2504]=true, - [2507]=true, - [2508]=true, - [2622]=true, - [2623]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2750]=true, - [2751]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2879]=true, - [2880]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2887]=true, - [2888]=true, - [2891]=true, - [2892]=true, - [2914]=true, - [2915]=true, - [3006]=true, - [3007]=true, - [3008]=true, - [3009]=true, - [3010]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3018]=true, - [3019]=true, - [3020]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3142]=true, - [3143]=true, - [3144]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3170]=true, - [3171]=true, - [3262]=true, - [3263]=true, - [3264]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3270]=true, - [3271]=true, - [3272]=true, - [3274]=true, - [3275]=true, - [3276]=true, - [3285]=true, - [3286]=true, - [3298]=true, - [3299]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3398]=true, - [3399]=true, - [3400]=true, - [3402]=true, - [3403]=true, - [3404]=true, - [3415]=true, - [3426]=true, - [3427]=true, - [4139]=true, - [4140]=true, - [4141]=true, - [4142]=true, - [4143]=true, - [4144]=true, - [4145]=true, - [4146]=true, - [4147]=true, - [4148]=true, - [4149]=true, - [4182]=true, - [4183]=true, - [4184]=true, - [4185]=true, - [4194]=true, - [4199]=true, - [4200]=true, - [4209]=true, - [4210]=true, - [4211]=true, - [4212]=true, - [4227]=true, - [4228]=true, - [4229]=true, - [4230]=true, - [4252]=true, - [4253]=true, - [43493]=true, - }, - ["halant"]={ - [2381]=true, - [2509]=true, - [2637]=true, - [2765]=true, - [2893]=true, - [3021]=true, - [3149]=true, - [3277]=true, - [3405]=true, - }, - ["independent_vowel"]={ - [2308]=true, - [2309]=true, - [2310]=true, - [2311]=true, - [2312]=true, - [2313]=true, - [2314]=true, - [2315]=true, - [2316]=true, - [2317]=true, - [2318]=true, - [2319]=true, - [2320]=true, - [2321]=true, - [2322]=true, - [2323]=true, - [2324]=true, - [2400]=true, - [2401]=true, - [2418]=true, - [2419]=true, - [2420]=true, - [2421]=true, - [2422]=true, - [2423]=true, - [2437]=true, - [2438]=true, - [2439]=true, - [2440]=true, - [2441]=true, - [2442]=true, - [2443]=true, - [2444]=true, - [2447]=true, - [2448]=true, - [2451]=true, - [2452]=true, - [2528]=true, - [2529]=true, - [2530]=true, - [2531]=true, - [2565]=true, - [2566]=true, - [2567]=true, - [2568]=true, - [2569]=true, - [2570]=true, - [2575]=true, - [2576]=true, - [2579]=true, - [2580]=true, - [2693]=true, - [2694]=true, - [2695]=true, - [2696]=true, - [2697]=true, - [2698]=true, - [2699]=true, - [2700]=true, - [2701]=true, - [2703]=true, - [2704]=true, - [2705]=true, - [2707]=true, - [2708]=true, - [2784]=true, - [2785]=true, - [2786]=true, - [2787]=true, - [2821]=true, - [2822]=true, - [2823]=true, - [2824]=true, - [2825]=true, - [2826]=true, - [2827]=true, - [2828]=true, - [2831]=true, - [2832]=true, - [2835]=true, - [2836]=true, - [2912]=true, - [2913]=true, - [2949]=true, - [2950]=true, - [2951]=true, - [2952]=true, - [2953]=true, - [2954]=true, - [2958]=true, - [2959]=true, - [2960]=true, - [2962]=true, - [2963]=true, - [2964]=true, - [3077]=true, - [3078]=true, - [3079]=true, - [3080]=true, - [3081]=true, - [3082]=true, - [3083]=true, - [3084]=true, - [3086]=true, - [3087]=true, - [3088]=true, - [3090]=true, - [3091]=true, - [3092]=true, - [3168]=true, - [3169]=true, - [3205]=true, - [3206]=true, - [3207]=true, - [3208]=true, - [3209]=true, - [3210]=true, - [3211]=true, - [3212]=true, - [3214]=true, - [3215]=true, - [3216]=true, - [3218]=true, - [3219]=true, - [3220]=true, - [3296]=true, - [3297]=true, - [3333]=true, - [3334]=true, - [3335]=true, - [3336]=true, - [3337]=true, - [3338]=true, - [3339]=true, - [3340]=true, - [3342]=true, - [3343]=true, - [3344]=true, - [3346]=true, - [3347]=true, - [3348]=true, - [3423]=true, - [3424]=true, - [3425]=true, - [4129]=true, - [4130]=true, - [4131]=true, - [4132]=true, - [4133]=true, - [4134]=true, - [4135]=true, - [4136]=true, - [4137]=true, - [4138]=true, - [4178]=true, - [4179]=true, - [4180]=true, - [4181]=true, - }, - ["nukta"]={ - [2364]=true, - [2492]=true, - [2620]=true, - [2748]=true, - [2876]=true, - [3260]=true, - }, - ["post_mark"]={ - [2307]=true, - [2363]=true, - [2366]=true, - [2368]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2383]=true, - [2494]=true, - [2496]=true, - [2622]=true, - [2624]=true, - [2750]=true, - [2752]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2880]=true, - [3006]=true, - [3007]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3262]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3276]=true, - [3285]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3415]=true, - [4139]=true, - [4140]=true, - [4152]=true, - [4155]=true, - [4182]=true, - [4183]=true, - [4194]=true, - [4195]=true, - [4196]=true, - [4199]=true, - [4200]=true, - [4201]=true, - [4202]=true, - [4203]=true, - [4204]=true, - [4205]=true, - [4227]=true, - [4231]=true, - [4232]=true, - [4233]=true, - [4234]=true, - [4235]=true, - [4236]=true, - [4239]=true, - [4250]=true, - [4251]=true, - [4252]=true, - [43643]=true, - [43645]=true, - }, - ["pre_mark"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2503]=true, - [2504]=true, - [2623]=true, - [2751]=true, - [2887]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, - [4145]=true, - [4228]=true, - }, - ["ra"]={ - [2352]=true, - [2480]=true, - [2544]=true, - [2608]=true, - [2736]=true, - [2864]=true, - [2992]=true, - [3120]=true, - [3248]=true, - [3376]=true, - }, - ["stress_tone_mark"]={ - [2385]=true, - [2386]=true, - [2387]=true, - [2388]=true, - [4151]=true, - [4195]=true, - [4196]=true, - [4201]=true, - [4202]=true, - [4203]=true, - [4204]=true, - [4205]=true, - [4231]=true, - [4232]=true, - [4233]=true, - [4234]=true, - [4235]=true, - [4236]=true, - [4237]=true, - [4239]=true, - [4250]=true, - [4251]=true, - [43643]=true, - [43644]=true, - [43645]=true, - }, - ["twopart_mark"]={ - [2507]={ 2503,2494 }, - [2508]={ 2503,2519 }, - [2888]={ 2887,2902 }, - [2891]={ 2887,2878 }, - [2892]={ 2887,2903 }, - [3018]={ 3014,3006 }, - [3019]={ 3015,3006 }, - [3020]={ 3014,3031 }, - [3144]={ 3142,3158 }, - [3264]={ 3263,3285 }, - [3271]={ 3270,3285 }, - [3272]={ 3270,3286 }, - [3274]={ 3270,3266 }, - [3275]={ 3274,3285 }, - [3402]={ 3398,3390 }, - [3403]={ 3399,3390 }, - [3404]={ 3398,3415 }, - }, - ["vowel_modifier"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2307]=true, - [2433]=true, - [3330]=true, - [3331]=true, - [4150]=true, - [4152]=true, - [4153]=true, - [4154]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43249]=true, - }, -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] --- - -if not modules then modules={} end modules ['font-ini']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local allocate=utilities.storage.allocate -local sortedhash=table.sortedhash -fonts=fonts or {} -local fonts=fonts -local identifiers=allocate() -fonts.hashes=fonts.hashes or { identifiers=identifiers } -fonts.tables=fonts.tables or {} -fonts.helpers=fonts.helpers or {} -fonts.tracers=fonts.tracers or {} -fonts.specifiers=fonts.specifiers or {} -fonts.analyzers={} -fonts.readers={} -fonts.definers={ methods={} } -fonts.loggers={ register=function() end } -if context then - font.originaleach=font.each - function font.each() - return sortedhash(identifiers) - end - fontloader=nil -end -fonts.privateoffsets={ - textbase=0xF0000, - textextrabase=0xFD000, - mathextrabase=0xFE000, - mathbase=0xFF000, - keepnames=false, -} -if node and not tex.getfontoffamily then - tex.getfontoffamily=node.family_font -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- - -if not modules then modules={} end modules ['luatex-font-mis']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local currentfont=font.current -local hashes=fonts.hashes -local identifiers=hashes.identifiers or {} -local marks=hashes.marks or {} -hashes.identifiers=identifiers -hashes.marks=marks -table.setmetatableindex(marks,function(t,k) - if k==true then - return marks[currentfont()] - else - local resources=identifiers[k].resources or {} - local marks=resources.marks or {} - t[k]=marks - return marks - end -end) -function font.each() - return table.sortedhash(fonts.hashes.identifiers) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con” cbccccc4a5016196d62332a365aa8b72] --- - -if not modules then modules={} end modules ['font-con']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget -local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find -local sort,insert,concat=table.sort,table.insert,table.concat -local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy -local derivetable=table.derive -local ioflush=io.flush -local round=math.round -local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) -local report_defining=logs.reporter("fonts","defining") -local fonts=fonts -local constructors=fonts.constructors or {} -fonts.constructors=constructors -local handlers=fonts.handlers or {} -fonts.handlers=handlers -local allocate=utilities.storage.allocate -local setmetatableindex=table.setmetatableindex -constructors.dontembed=allocate() -constructors.namemode="fullpath" -constructors.version=1.01 -constructors.cache=containers.define("fonts","constructors",constructors.version,false) -constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 -constructors.cacheintex=true -constructors.addtounicode=true -constructors.fixprotrusion=true -local designsizes=allocate() -constructors.designsizes=designsizes -local loadedfonts=allocate() -constructors.loadedfonts=loadedfonts -local factors={ - pt=65536.0, - bp=65781.8, -} -function constructors.setfactor(f) - constructors.factor=factors[f or 'pt'] or factors.pt -end -constructors.setfactor() -function constructors.scaled(scaledpoints,designsize) - if scaledpoints<0 then - local factor=constructors.factor - if designsize then - if designsize>factor then - return (- scaledpoints/1000)*designsize - else - return (- scaledpoints/1000)*designsize*factor - end - else - return (- scaledpoints/1000)*10*factor - end - else - return scaledpoints - end -end -function constructors.getprivate(tfmdata) - local properties=tfmdata.properties - local private=properties.private - properties.private=private+1 - return private -end -function constructors.setmathparameter(tfmdata,name,value) - local m=tfmdata.mathparameters - local c=tfmdata.MathConstants - if m then - m[name]=value - end - if c and c~=m then - c[name]=value - end -end -function constructors.getmathparameter(tfmdata,name) - local p=tfmdata.mathparameters or tfmdata.MathConstants - if p then - return p[name] - end -end -function constructors.cleanuptable(tfmdata) -end -function constructors.calculatescale(tfmdata,scaledpoints) - local parameters=tfmdata.parameters - if scaledpoints<0 then - scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) - end - return scaledpoints,scaledpoints/(parameters.units or 1000) -end -local unscaled={ - ScriptPercentScaleDown=true, - ScriptScriptPercentScaleDown=true, - RadicalDegreeBottomRaisePercent=true, - NoLimitSupFactor=true, - NoLimitSubFactor=true, -} -function constructors.assignmathparameters(target,original) - local mathparameters=original.mathparameters - if mathparameters and next(mathparameters) then - local targetparameters=target.parameters - local targetproperties=target.properties - local targetmathparameters={} - local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor - for name,value in next,mathparameters do - if unscaled[name] then - targetmathparameters[name]=value - else - targetmathparameters[name]=value*factor - end - end - if not targetmathparameters.FractionDelimiterSize then - targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size - end - if not mathparameters.FractionDelimiterDisplayStyleSize then - targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size - end - if not targetmathparameters.SpaceBeforeScript then - targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript - end - target.mathparameters=targetmathparameters - end -end -function constructors.beforecopyingcharacters(target,original) -end -function constructors.aftercopyingcharacters(target,original) -end -local nofinstances=0 -local instances=setmetatableindex(function(t,k) - nofinstances=nofinstances+1 - t[k]=nofinstances - return nofinstances -end) -function constructors.trytosharefont(target,tfmdata) - local properties=target.properties - local instance=properties.instance - if instance then - local fullname=target.fullname - local fontname=target.fontname - local psname=target.psname - local format=tfmdata.properties.format - if format=="opentype" then - target.streamprovider=1 - elseif format=="truetype" then - target.streamprovider=2 - else - target.streamprovider=0 - end - if target.streamprovider>0 then - if fullname then - fullname=fullname..":"..instances[instance] - target.fullname=fullname - end - if fontname then - fontname=fontname..":"..instances[instance] - target.fontname=fontname - end - if psname then - psname=psname..":"..instances[instance] - target.psname=psname - end - end - end -end -local synonyms={ - exheight="x_height", - xheight="x_height", - ex="x_height", - emwidth="quad", - em="quad", - spacestretch="space_stretch", - stretch="space_stretch", - spaceshrink="space_shrink", - shrink="space_shrink", - extraspace="extra_space", - xspace="extra_space", - slantperpoint="slant", -} -function constructors.enhanceparameters(parameters) - local mt=getmetatable(parameters) - local getter=function(t,k) - if not k then - return nil - end - local s=synonyms[k] - if s then - return rawget(t,s) or (mt and mt[s]) or nil - end - if k=="spacing" then - return { - width=t.space, - stretch=t.space_stretch, - shrink=t.space_shrink, - extra=t.extra_space, - } - end - return mt and mt[k] or nil - end - local setter=function(t,k,v) - if not k then - return 0 - end - local s=synonyms[k] - if s then - rawset(t,s,v) - elseif k=="spacing" then - if type(v)=="table" then - rawset(t,"space",v.width or 0) - rawset(t,"space_stretch",v.stretch or 0) - rawset(t,"space_shrink",v.shrink or 0) - rawset(t,"extra_space",v.extra or 0) - end - else - rawset(t,k,v) - end - end - setmetatable(parameters,{ - __index=getter, - __newindex=setter, - }) -end -local function mathkerns(v,vdelta) - local k={} - for i=1,#v do - local entry=v[i] - local height=entry.height - local kern=entry.kern - k[i]={ - height=height and vdelta*height or 0, - kern=kern and vdelta*kern or 0, - } - end - return k -end -local psfake=0 -local function fixedpsname(psname,fallback) - local usedname=psname - if psname and psname~="" then - if find(psname," ",1,true) then - usedname=gsub(psname,"[%s]+","-") - else - end - elseif not fallback or fallback=="" then - psfake=psfake+1 - psname="fakename-"..psfake - else - psname=fallback - usedname=gsub(psname,"[^a-zA-Z0-9]+","-") - end - return usedname,psname~=usedname -end -function constructors.scale(tfmdata,specification) - local target={} - if tonumber(specification) then - specification={ size=specification } - end - target.specification=specification - local scaledpoints=specification.size - local relativeid=specification.relativeid - local properties=tfmdata.properties or {} - local goodies=tfmdata.goodies or {} - local resources=tfmdata.resources or {} - local descriptions=tfmdata.descriptions or {} - local characters=tfmdata.characters or {} - local changed=tfmdata.changed or {} - local shared=tfmdata.shared or {} - local parameters=tfmdata.parameters or {} - local mathparameters=tfmdata.mathparameters or {} - local targetcharacters={} - local targetdescriptions=derivetable(descriptions) - local targetparameters=derivetable(parameters) - local targetproperties=derivetable(properties) - local targetgoodies=goodies - target.characters=targetcharacters - target.descriptions=targetdescriptions - target.parameters=targetparameters - target.properties=targetproperties - target.goodies=targetgoodies - target.shared=shared - target.resources=resources - target.unscaled=tfmdata - local mathsize=tonumber(specification.mathsize) or 0 - local textsize=tonumber(specification.textsize) or scaledpoints - local forcedsize=tonumber(parameters.mathsize ) or 0 - local extrafactor=tonumber(specification.factor ) or 1 - if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then - scaledpoints=parameters.scriptpercentage*textsize/100 - elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then - scaledpoints=parameters.scriptscriptpercentage*textsize/100 - elseif forcedsize>1000 then - scaledpoints=forcedsize - else - end - targetparameters.mathsize=mathsize - targetparameters.textsize=textsize - targetparameters.forcedsize=forcedsize - targetparameters.extrafactor=extrafactor - local addtounicode=constructors.addtounicode - local tounicode=fonts.mappings.tounicode - local unknowncode=tounicode(0xFFFD) - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local units=parameters.units or 1000 - targetproperties.language=properties.language or "dflt" - targetproperties.script=properties.script or "dflt" - targetproperties.mode=properties.mode or "base" - targetproperties.method=properties.method - local askedscaledpoints=scaledpoints - local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) - local hdelta=delta - local vdelta=delta - target.designsize=parameters.designsize - target.units=units - target.units_per_em=units - local direction=properties.direction or tfmdata.direction or 0 - target.direction=direction - properties.direction=direction - target.size=scaledpoints - target.encodingbytes=properties.encodingbytes or 1 - target.subfont=properties.subfont - target.embedding=properties.embedding or "subset" - target.tounicode=1 - target.cidinfo=properties.cidinfo - target.format=properties.format - target.cache=constructors.cacheintex and "yes" or "renew" - local original=properties.original or tfmdata.original - local fontname=properties.fontname or tfmdata.fontname - local fullname=properties.fullname or tfmdata.fullname - local filename=properties.filename or tfmdata.filename - local psname=properties.psname or tfmdata.psname - local name=properties.name or tfmdata.name - local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) - target.original=original - target.fontname=fontname - target.fullname=fullname - target.filename=filename - target.psname=psname - target.name=name - properties.fontname=fontname - properties.fullname=fullname - properties.filename=filename - properties.psname=psname - properties.name=name - local expansion=parameters.expansion - if expansion then - target.stretch=expansion.stretch - target.shrink=expansion.shrink - target.step=expansion.step - end - local slantfactor=parameters.slantfactor or 0 - if slantfactor~=0 then - target.slant=slantfactor*1000 - else - target.slant=0 - end - local extendfactor=parameters.extendfactor or 0 - if extendfactor~=0 and extendfactor~=1 then - hdelta=hdelta*extendfactor - target.extend=extendfactor*1000 - else - target.extend=1000 - end - local squeezefactor=parameters.squeezefactor or 0 - if squeezefactor~=0 and squeezefactor~=1 then - vdelta=vdelta*squeezefactor - target.squeeze=squeezefactor*1000 - else - target.squeeze=1000 - end - local mode=parameters.mode or 0 - if mode~=0 then - target.mode=mode - end - local width=parameters.width or 0 - if width~=0 then - target.width=width*delta*1000/655360 - end - targetparameters.factor=delta - targetparameters.hfactor=hdelta - targetparameters.vfactor=vdelta - targetparameters.size=scaledpoints - targetparameters.units=units - targetparameters.scaledpoints=askedscaledpoints - targetparameters.mode=mode - targetparameters.width=width - local isvirtual=properties.virtualized or tfmdata.type=="virtual" - local hasquality=parameters.expansion or parameters.protrusion - local hasitalics=properties.hasitalics - local autoitalicamount=properties.autoitalicamount - local stackmath=not properties.nostackmath - local haskerns=properties.haskerns or properties.mode=="base" - local hasligatures=properties.hasligatures or properties.mode=="base" - local realdimensions=properties.realdimensions - local writingmode=properties.writingmode or "horizontal" - local identity=properties.identity or "horizontal" - local vfonts=target.fonts - if vfonts and #vfonts>0 then - target.fonts=fastcopy(vfonts) - elseif isvirtual then - target.fonts={ { id=0 } } - end - if changed and not next(changed) then - changed=false - end - target.type=isvirtual and "virtual" or "real" - target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" - target.identity=identity=="vertical" and "vertical" or "horizontal" - target.postprocessors=tfmdata.postprocessors - local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt - local targetspace=(parameters.space or parameters[2] or 0)*hdelta - local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta - local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta - local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta - local targetquad=(parameters.quad or parameters[6] or 0)*hdelta - local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta - targetparameters.slant=targetslant - targetparameters.space=targetspace - targetparameters.space_stretch=targetspace_stretch - targetparameters.space_shrink=targetspace_shrink - targetparameters.x_height=targetx_height - targetparameters.quad=targetquad - targetparameters.extra_space=targetextra_space - local hshift=parameters.hshift - if hshift then - targetparameters.hshift=delta*hshift - end - local vshift=parameters.vshift - if vshift then - targetparameters.vshift=delta*vshift - end - local ascender=parameters.ascender - if ascender then - targetparameters.ascender=delta*ascender - end - local descender=parameters.descender - if descender then - targetparameters.descender=delta*descender - end - constructors.enhanceparameters(targetparameters) - local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 - local scaledwidth=defaultwidth*hdelta - local scaledheight=defaultheight*vdelta - local scaleddepth=defaultdepth*vdelta - local hasmath=(properties.hasmath or next(mathparameters)) and true - if hasmath then - constructors.assignmathparameters(target,tfmdata) - properties.hasmath=true - target.nomath=false - target.MathConstants=target.mathparameters - else - properties.hasmath=false - target.nomath=true - target.mathparameters=nil - end - if hasmath then - local mathitalics=properties.mathitalics - if mathitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - else - local textitalics=properties.textitalics - if textitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - end - if trace_defining then - report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, - hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") - end - constructors.beforecopyingcharacters(target,tfmdata) - local sharedkerns={} - for unicode,character in next,characters do - local chr,description,index - if changed then - local c=changed[unicode] - if c and c~=unicode then - if c then - description=descriptions[c] or descriptions[unicode] or character - character=characters[c] or character - index=description.index or c - else - description=descriptions[unicode] or character - index=description.index or unicode - end - else - description=descriptions[unicode] or character - index=description.index or unicode - end - else - description=descriptions[unicode] or character - index=description.index or unicode - end - local width=description.width - local height=description.height - local depth=description.depth - local isunicode=description.unicode - if realdimensions then - if not height or height==0 then - local bb=description.boundingbox - local ht=bb[4] - if ht~=0 then - height=ht - end - if not depth or depth==0 then - local dp=-bb[2] - if dp~=0 then - depth=dp - end - end - elseif not depth or depth==0 then - local dp=-description.boundingbox[2] - if dp~=0 then - depth=dp - end - end - end - if width then width=hdelta*width else width=scaledwidth end - if height then height=vdelta*height else height=scaledheight end - if depth and depth~=0 then - depth=delta*depth - if isunicode then - chr={ - index=index, - height=height, - depth=depth, - width=width, - unicode=isunicode, - } - else - chr={ - index=index, - height=height, - depth=depth, - width=width, - } - end - else - if isunicode then - chr={ - index=index, - height=height, - width=width, - unicode=isunicode, - } - else - chr={ - index=index, - height=height, - width=width, - } - end - end - if addtounicode then - chr.tounicode=isunicode and tounicode(isunicode) or unknowncode - end - if hasquality then - local ve=character.expansion_factor - if ve then - chr.expansion_factor=ve*1000 - end - local vl=character.left_protruding - if vl then - chr.left_protruding=protrusionfactor*width*vl - end - local vr=character.right_protruding - if vr then - chr.right_protruding=protrusionfactor*width*vr - end - end - if hasmath then - local vn=character.next - if vn then - chr.next=vn - else - local vv=character.vert_variants - if vv then - local t={} - for i=1,#vv do - local vvi=vv[i] - local s=vvi["start"] or 0 - local e=vvi["end"] or 0 - local a=vvi["advance"] or 0 - t[i]={ - ["start"]=s==0 and 0 or s*vdelta, - ["end"]=e==0 and 0 or e*vdelta, - ["advance"]=a==0 and 0 or a*vdelta, - ["extender"]=vvi["extender"], - ["glyph"]=vvi["glyph"], - } - end - chr.vert_variants=t - else - local hv=character.horiz_variants - if hv then - local t={} - for i=1,#hv do - local hvi=hv[i] - local s=hvi["start"] or 0 - local e=hvi["end"] or 0 - local a=hvi["advance"] or 0 - t[i]={ - ["start"]=s==0 and 0 or s*hdelta, - ["end"]=e==0 and 0 or e*hdelta, - ["advance"]=a==0 and 0 or a*hdelta, - ["extender"]=hvi["extender"], - ["glyph"]=hvi["glyph"], - } - end - chr.horiz_variants=t - end - end - end - local vi=character.vert_italic - if vi and vi~=0 then - chr.vert_italic=vi*hdelta - end - local va=character.accent - if va then - chr.top_accent=vdelta*va - end - if stackmath then - local mk=character.mathkerns - if mk then - local tr=mk.topright - local tl=mk.topleft - local br=mk.bottomright - local bl=mk.bottomleft - chr.mathkern={ - top_right=tr and mathkerns(tr,vdelta) or nil, - top_left=tl and mathkerns(tl,vdelta) or nil, - bottom_right=br and mathkerns(br,vdelta) or nil, - bottom_left=bl and mathkerns(bl,vdelta) or nil, - } - end - end - if hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end - end - elseif autoitalicamount then - local vi=description.italic - if not vi then - local bb=description.boundingbox - if bb then - local vi=bb[3]-description.width+autoitalicamount - if vi>0 then - chr.italic=vi*hdelta - end - else - end - elseif vi~=0 then - chr.italic=vi*hdelta - end - elseif hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end - end - if haskerns then - local vk=character.kerns - if vk then - local s=sharedkerns[vk] - if not s then - s={} - for k,v in next,vk do s[k]=v*hdelta end - sharedkerns[vk]=s - end - chr.kerns=s - end - end - if hasligatures then - local vl=character.ligatures - if vl then - if true then - chr.ligatures=vl - else - local tt={} - for i,l in next,vl do - tt[i]=l - end - chr.ligatures=tt - end - end - end - if isvirtual then - local vc=character.commands - if vc then - local ok=false - for i=1,#vc do - local key=vc[i][1] - if key=="right" or key=="down" or key=="rule" then - ok=true - break - end - end - if ok then - local tt={} - for i=1,#vc do - local ivc=vc[i] - local key=ivc[1] - if key=="right" then - tt[i]={ key,ivc[2]*hdelta } - elseif key=="down" then - tt[i]={ key,ivc[2]*vdelta } - elseif key=="rule" then - tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } - else - tt[i]=ivc - end - end - chr.commands=tt - else - chr.commands=vc - end - end - end - targetcharacters[unicode]=chr - end - properties.setitalics=hasitalics - constructors.aftercopyingcharacters(target,tfmdata) - constructors.trytosharefont(target,tfmdata) - local vfonts=target.fonts - if isvirtual or target.type=="virtual" or properties.virtualized then - properties.virtualized=true - target.type="virtual" - if not vfonts or #vfonts==0 then - target.fonts={ { id=0 } } - end - elseif vfonts then - properties.virtualized=true - target.type="virtual" - if #vfonts==0 then - target.fonts={ { id=0 } } - end - end - return target -end -function constructors.finalize(tfmdata) - if tfmdata.properties and tfmdata.properties.finalized then - return - end - if not tfmdata.characters then - return nil - end - if not tfmdata.goodies then - tfmdata.goodies={} - end - local parameters=tfmdata.parameters - if not parameters then - return nil - end - if not parameters.expansion then - parameters.expansion={ - stretch=tfmdata.stretch or 0, - shrink=tfmdata.shrink or 0, - step=tfmdata.step or 0, - } - end - if not parameters.size then - parameters.size=tfmdata.size - end - if not parameters.mode then - parameters.mode=0 - end - if not parameters.width then - parameters.width=0 - end - if not parameters.slantfactor then - parameters.slantfactor=(tfmdata.slant or 0)/1000 - end - if not parameters.extendfactor then - parameters.extendfactor=(tfmdata.extend or 1000)/1000 - end - if not parameters.squeezefactor then - parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000 - end - local designsize=parameters.designsize - if designsize then - parameters.minsize=tfmdata.minsize or designsize - parameters.maxsize=tfmdata.maxsize or designsize - else - designsize=factors.pt*10 - parameters.designsize=designsize - parameters.minsize=designsize - parameters.maxsize=designsize - end - parameters.minsize=tfmdata.minsize or parameters.designsize - parameters.maxsize=tfmdata.maxsize or parameters.designsize - if not parameters.units then - parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 - end - if not tfmdata.descriptions then - local descriptions={} - setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) - tfmdata.descriptions=descriptions - end - local properties=tfmdata.properties - if not properties then - properties={} - tfmdata.properties=properties - end - if not properties.virtualized then - properties.virtualized=tfmdata.type=="virtual" - end - properties.fontname=properties.fontname or tfmdata.fontname - properties.filename=properties.filename or tfmdata.filename - properties.fullname=properties.fullname or tfmdata.fullname - properties.name=properties.name or tfmdata.name - properties.psname=properties.psname or tfmdata.psname - properties.encodingbytes=tfmdata.encodingbytes or 1 - properties.subfont=tfmdata.subfont or nil - properties.embedding=tfmdata.embedding or "subset" - properties.tounicode=tfmdata.tounicode or 1 - properties.cidinfo=tfmdata.cidinfo or nil - properties.format=tfmdata.format or "type1" - properties.direction=tfmdata.direction or 0 - properties.writingmode=tfmdata.writingmode or "horizontal" - properties.identity=tfmdata.identity or "horizontal" - properties.usedbitmap=tfmdata.usedbitmap - if not tfmdata.resources then - tfmdata.resources={} - end - if not tfmdata.shared then - tfmdata.shared={} - end - if not properties.hasmath then - properties.hasmath=not tfmdata.nomath - end - tfmdata.MathConstants=nil - tfmdata.postprocessors=nil - tfmdata.fontname=nil - tfmdata.filename=nil - tfmdata.fullname=nil - tfmdata.name=nil - tfmdata.psname=nil - tfmdata.encodingbytes=nil - tfmdata.subfont=nil - tfmdata.embedding=nil - tfmdata.tounicode=nil - tfmdata.cidinfo=nil - tfmdata.format=nil - tfmdata.direction=nil - tfmdata.type=nil - tfmdata.nomath=nil - tfmdata.designsize=nil - tfmdata.size=nil - tfmdata.stretch=nil - tfmdata.shrink=nil - tfmdata.step=nil - tfmdata.slant=nil - tfmdata.extend=nil - tfmdata.squeeze=nil - tfmdata.mode=nil - tfmdata.width=nil - tfmdata.units=nil - tfmdata.units_per_em=nil - tfmdata.cache=nil - properties.finalized=true - return tfmdata -end -local hashmethods={} -constructors.hashmethods=hashmethods -function constructors.hashfeatures(specification) - local features=specification.features - if features then - local t,n={},0 - for category,list in sortedhash(features) do - if next(list) then - local hasher=hashmethods[category] - if hasher then - local hash=hasher(list) - if hash then - n=n+1 - t[n]=category..":"..hash - end - end - end - end - if n>0 then - return concat(t," & ") - end - end - return "unknown" -end -hashmethods.normal=function(list) - local s={} - local n=0 - for k,v in next,list do - if not k then - elseif k=="number" or k=="features" then - else - n=n+1 - if type(v)=="table" then - local t={} - local m=0 - for k,v in next,v do - m=m+1 - t[m]=k..'='..tostring(v) - end - sort(t) - s[n]=k..'={'..concat(t,",").."}" - else - s[n]=k..'='..tostring(v) - end - end - end - if n>0 then - sort(s) - return concat(s,"+") - end -end -function constructors.hashinstance(specification,force) - local hash=specification.hash - local size=specification.size - local fallbacks=specification.fallbacks - if force or not hash then - hash=constructors.hashfeatures(specification) - specification.hash=hash - end - if size<1000 and designsizes[hash] then - size=round(constructors.scaled(size,designsizes[hash])) - else - size=round(size) - end - specification.size=size - if fallbacks then - return hash..' @ '..size..' @ '..fallbacks - else - return hash..' @ '..size - end -end -function constructors.setname(tfmdata,specification) - if constructors.namemode=="specification" then - local specname=specification.specification - if specname then - tfmdata.properties.name=specname - if trace_defining then - report_otf("overloaded fontname %a",specname) - end - end - end -end -function constructors.checkedfilename(data) - local foundfilename=data.foundfilename - if not foundfilename then - local askedfilename=data.filename or "" - if askedfilename~="" then - askedfilename=resolvers.resolve(askedfilename) - foundfilename=resolvers.findbinfile(askedfilename,"") or "" - if foundfilename=="" then - report_defining("source file %a is not found",askedfilename) - foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" - if foundfilename~="" then - report_defining("using source file %a due to cache mismatch",foundfilename) - end - end - end - data.foundfilename=foundfilename - end - return foundfilename -end -local formats=allocate() -fonts.formats=formats -setmetatableindex(formats,function(t,k) - local l=lower(k) - if rawget(t,k) then - t[k]=l - return l - end - return rawget(t,file.suffix(l)) -end) -do - local function setindeed(mode,source,target,group,name,position) - local action=source[mode] - if not action then - return - end - local t=target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - insert(t,position,{ name=name,action=action }) - else - for i=1,#t do - local ti=t[i] - if ti.name==name then - ti.action=action - return - end - end - insert(t,{ name=name,action=action }) - end - end - local function set(group,name,target,source) - target=target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source=source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local position=source.position - setindeed("node",source,target,group,name,position) - setindeed("base",source,target,group,name,position) - setindeed("plug",source,target,group,name,position) - end - local function register(where,specification) - local name=specification.name - if name and name~="" then - local default=specification.default - local description=specification.description - local initializers=specification.initializers - local processors=specification.processors - local manipulators=specification.manipulators - local modechecker=specification.modechecker - if default then - where.defaults[name]=default - end - if description and description~="" then - where.descriptions[name]=description - end - if initializers then - set('initializers',name,where,specification) - end - if processors then - set('processors',name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) - end - if modechecker then - where.modechecker=modechecker - end - end - end - constructors.registerfeature=register - function constructors.getfeatureaction(what,where,mode,name) - what=handlers[what].features - if what then - where=what[where] - if where then - mode=where[mode] - if mode then - for i=1,#mode do - local m=mode[i] - if m.name==name then - return m.action - end - end - end - end - end - end - local newfeatures={} - constructors.newfeatures=newfeatures - constructors.features=newfeatures - local function setnewfeatures(what) - local handler=handlers[what] - local features=handler.features - if not features then - local tables=handler.tables - local statistics=handler.statistics - features=allocate { - defaults={}, - descriptions=tables and tables.features or {}, - used=statistics and statistics.usedfeatures or {}, - initializers={ base={},node={},plug={} }, - processors={ base={},node={},plug={} }, - manipulators={ base={},node={},plug={} }, - } - features.register=function(specification) return register(features,specification) end - handler.features=features - end - return features - end - setmetatable(newfeatures,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, - }) -end -do - local newhandler={} - constructors.handlers=newhandler - constructors.newhandler=newhandler - local function setnewhandler(what) - local handler=handlers[what] - if not handler then - handler={} - handlers[what]=handler - end - return handler - end - setmetatable(newhandler,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, - }) -end -do - local newenhancer={} - constructors.enhancers=newenhancer - constructors.newenhancer=newenhancer - local function setnewenhancer(format) - local handler=handlers[format] - local enhancers=handler.enhancers - if not enhancers then - local actions=allocate() - local before=allocate() - local after=allocate() - local order=allocate() - local known={} - local nofsteps=0 - local patches={ before=before,after=after } - local trace=false - local report=logs.reporter("fonts",format.." enhancing") - trackers.register(format..".loading",function(v) trace=v end) - local function enhance(name,data,filename,raw) - local enhancer=actions[name] - if enhancer then - if trace then - report("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - end - end - local function apply(data,filename,raw) - local basename=file.basename(lower(filename)) - if trace then - report("%s enhancing file %a","start",filename) - end - ioflush() - for e=1,nofsteps do - local enhancer=order[e] - local b=before[enhancer] - if b then - for pattern,action in next,b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a=after[enhancer] - if a then - for pattern,action in next,a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() - end - if trace then - report("%s enhancing file %a","stop",filename) - end - ioflush() - end - local function register(what,action) - if action then - if actions[what] then - else - nofsteps=nofsteps+1 - order[nofsteps]=what - known[what]=nofsteps - end - actions[what]=action - else - report("bad enhancer %a",what) - end - end - local function patch(what,where,pattern,action) - local pw=patches[what] - if pw then - local ww=pw[where] - if ww then - ww[pattern]=action - else - pw[where]={ [pattern]=action } - if not known[where] then - nofsteps=nofsteps+1 - order[nofsteps]=where - known[where]=nofsteps - end - end - end - end - enhancers={ - register=register, - apply=apply, - patch=patch, - report=report, - patches={ - register=patch, - report=report, - }, - } - handler.enhancers=enhancers - end - return enhancers - end - setmetatable(newenhancer,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, - }) -end -function constructors.checkedfeatures(what,features) - local defaults=handlers[what].features.defaults - if features and next(features) then - features=fastcopy(features) - for key,value in next,defaults do - if features[key]==nil then - features[key]=value - end - end - return features - else - return fastcopy(defaults) - end -end -function constructors.initializefeatures(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties or {} - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmodechecker=whatfeatures.modechecker - local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" - properties.mode=mode - features.mode=mode - local done={} - while true do - local redo=false - local initializers=whatfeatures.initializers[mode] - if initializers then - for i=1,#initializers do - local step=initializers[i] - local feature=step.name - local value=features[feature] - if not value then - elseif done[feature] then - else - local action=step.action - if trace then - report("initializing feature %a to %a for mode %a for font %a",feature, - value,mode,tfmdata.properties.fullname) - end - action(tfmdata,value,features) - if mode~=properties.mode or mode~=features.mode then - if whatmodechecker then - properties.mode=whatmodechecker(tfmdata,features,properties.mode) - features.mode=properties.mode - end - if mode~=properties.mode then - mode=properties.mode - redo=true - end - end - done[feature]=true - end - if redo then - break - end - end - if not redo then - break - end - else - break - end - end - properties.mode=mode - return true - else - return false - end -end -function constructors.collectprocessors(what,tfmdata,features,trace,report) - local processes={} - local nofprocesses=0 - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatprocessors=whatfeatures.processors - local mode=properties.mode - local processors=whatprocessors[mode] - if processors then - for i=1,#processors do - local step=processors[i] - local feature=step.name - if features[feature] then - local action=step.action - if trace then - report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) - end - if action then - nofprocesses=nofprocesses+1 - processes[nofprocesses]=action - end - end - end - elseif trace then - report("no feature processors for mode %a for font %a",mode,properties.fullname) - end - end - return processes -end -function constructors.applymanipulators(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmanipulators=whatfeatures.manipulators - local mode=properties.mode - local manipulators=whatmanipulators[mode] - if manipulators then - for i=1,#manipulators do - local step=manipulators[i] - local feature=step.name - local value=features[feature] - if value then - local action=step.action - if trace then - report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) - end - if action then - action(tfmdata,feature,value) - end - end - end - end - end -end -function constructors.addcoreunicodes(unicodes) - if not unicodes then - unicodes={} - end - unicodes.space=0x0020 - unicodes.hyphen=0x002D - unicodes.zwj=0x200D - unicodes.zwnj=0x200C - return unicodes -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- - -if not modules then modules={} end modules ['luatex-font-enc']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local fonts=fonts -local encodings={} -fonts.encodings=encodings -encodings.agl={} -encodings.known={} -setmetatable(encodings.agl,{ __index=function(t,k) - if k=="unicodes" then - logs.report("fonts","loading (extended) adobe glyph list") - local unicodes=dofile(resolvers.findfile("font-age.lua")) - encodings.agl={ unicodes=unicodes } - return unicodes - else - return nil - end -end }) -encodings.cache=containers.define("fonts","enc",encodings.version,true) -function encodings.load(filename) - local name=file.removesuffix(filename) - local data=containers.read(encodings.cache,name) - if data then - return data - end - local vector,tag,hash,unicodes={},"",{},{} - local foundname=resolvers.findfile(filename,'enc') - if foundname and foundname~="" then - local ok,encoding,size=resolvers.loadbinfile(foundname) - if ok and encoding then - encoding=string.gsub(encoding,"%%(.-)\n","") - local unicoding=encodings.agl.unicodes - local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") - local i=0 - for ch in string.gmatch(vec,"/([%a%d%.]+)") do - if ch~=".notdef" then - vector[i]=ch - if not hash[ch] then - hash[ch]=i - else - end - local u=unicoding[ch] - if u then - unicodes[u]=i - end - end - i=i+1 - end - end - end - local data={ - name=name, - tag=tag, - vector=vector, - hash=hash, - unicodes=unicodes - } - return containers.write(encodings.cache,name,data) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- - -if not modules then modules={} end modules ['font-cid']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local format,match,lower=string.format,string.match,string.lower -local tonumber=tonumber -local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match -local fonts,logs,trackers=fonts,logs,trackers -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local cid={} -fonts.cid=cid -local cidmap={} -local cidmax=10 -local number=C(R("09","af","AF")^1) -local space=S(" \n\r\t") -local spaces=space^0 -local period=P(".") -local periods=period*period -local name=P("/")*C((1-space)^1) -local unicodes,names={},{} -local function do_one(a,b) - unicodes[tonumber(a)]=tonumber(b,16) -end -local function do_range(a,b,c) - c=tonumber(c,16) - for i=tonumber(a),tonumber(b) do - unicodes[i]=c - c=c+1 - end -end -local function do_name(a,b) - names[tonumber(a)]=b -end -local grammar=P { "start", - start=number*spaces*number*V("series"), - series=(spaces*(V("one")+V("range")+V("named")))^1, - one=(number*spaces*number)/do_one, - range=(number*periods*number*spaces*number)/do_range, - named=(number*spaces*name)/do_name -} -local function loadcidfile(filename) - local data=io.loaddata(filename) - if data then - unicodes,names={},{} - lpegmatch(grammar,data) - local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") - return { - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes=unicodes, - names=names, - } - end -end -cid.loadfile=loadcidfile -local template="%s-%s-%s.cidmap" -local function locate(registry,ordering,supplement) - local filename=format(template,registry,ordering,supplement) - local hashname=lower(filename) - local found=cidmap[hashname] - if not found then - if trace_loading then - report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) - end - local fullname=resolvers.findfile(filename,'cid') or "" - if fullname~="" then - found=loadcidfile(fullname) - if found then - if trace_loading then - report_otf("using cidmap file %a",filename) - end - cidmap[hashname]=found - found.usedname=file.basename(filename) - end - end - end - return found -end -function cid.getmap(specification) - if not specification then - report_otf("invalid cidinfo specification, table expected") - return - end - local registry=specification.registry - local ordering=specification.ordering - local supplement=specification.supplement - local filename=format(registry,ordering,supplement) - local lowername=lower(filename) - local found=cidmap[lowername] - if found then - return found - end - if ordering=="Identity" then - local found={ - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes={}, - names={}, - } - cidmap[lowername]=found - return found - end - if trace_loading then - report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement) - end - found=locate(registry,ordering,supplement) - if not found then - local supnum=tonumber(supplement) - local cidnum=nil - if supnum0 then - for s=supnum-1,0,-1 do - local c=locate(registry,ordering,s) - if c then - found,cidnum=c,s - break - end - end - end - registry=lower(registry) - ordering=lower(ordering) - if found and cidnum>0 then - for s=0,cidnum-1 do - local filename=format(template,registry,ordering,s) - if not cidmap[filename] then - cidmap[filename]=found - end - end - end - end - return found -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map” a03653ea3c5f042b457d54ed678d6df3] --- - -if not modules then modules={} end modules ['font-map']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tonumber,next,type=tonumber,next,type -local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower -local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match -local formatters=string.formatters -local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys -local idiv=number.idiv -local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) -local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) -local report_fonts=logs.reporter("fonts","loading") -local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) -local fonts=fonts or {} -local mappings=fonts.mappings or {} -fonts.mappings=mappings -local allocate=utilities.storage.allocate -local hex=R("AF","af","09") -local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end -local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end -local dec=(R("09")^1)/tonumber -local period=P(".") -local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) -local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) -local index=P("index")*dec*Cc(false) -local parser=unicode+ucode+index -local parsers={} -local function makenameparser(str) - if not str or str=="" then - return parser - else - local p=parsers[str] - if not p then - p=P(str)*period*dec*Cc(false) - parsers[str]=p - end - return p - end -end -local f_single=formatters["%04X"] -local f_double=formatters["%04X%04X"] -local s_unknown="FFFD" -local function tounicode16(unicode) - if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then - return f_single(unicode) - elseif unicode>=0x00E000 and unicode<=0x00F8FF then - return s_unknown - elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then - return s_unknown - elseif unicode>=0x100000 and unicode<=0x10FFFF then - return s_unknown - elseif unicode>=0x00D800 and unicode<=0x00DFFF then - return s_unknown - else - unicode=unicode-0x10000 - return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00) - end -end -local function tounicode16sequence(unicodes) - local t={} - for l=1,#unicodes do - local u=unicodes[l] - if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then - t[l]=f_single(u) - elseif unicode>=0x00E000 and unicode<=0x00F8FF then - t[l]=s_unknown - elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then - t[l]=s_unknown - elseif unicode>=0x100000 and unicode<=0x10FFFF then - t[l]=s_unknown - elseif unicode>=0x00D7FF and unicode<=0x00DFFF then - t[l]=s_unknown - else - u=u-0x10000 - t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00) - end - end - return concat(t) -end -local hash={} -local conc={} -table.setmetatableindex(hash,function(t,k) - local v - if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then - v=f_single(k) - else - local k=k-0x10000 - v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00) - end - t[k]=v - return v -end) -local function tounicode(k) - if type(k)=="table" then - local n=#k - for l=1,n do - conc[l]=hash[k[l]] - end - return concat(conc,"",1,n) - elseif k>=0x00E000 and k<=0x00F8FF then - return s_unknown - elseif k>=0x0F0000 and k<=0x0FFFFF then - return s_unknown - elseif k>=0x100000 and k<=0x10FFFF then - return s_unknown - elseif k>=0x00D7FF and k<=0x00DFFF then - return s_unknown - else - return hash[k] - end -end -local function fromunicode16(str) - if #str==4 then - return tonumber(str,16) - else - local l,r=match(str,"(....)(....)") - return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 - end -end -mappings.makenameparser=makenameparser -mappings.tounicode=tounicode -mappings.tounicode16=tounicode16 -mappings.tounicode16sequence=tounicode16sequence -mappings.fromunicode16=fromunicode16 -local ligseparator=P("_") -local varseparator=P(".") -local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) -do - local overloads={ - IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, - ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, - ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, - fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, - fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, - ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, - ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, - fj={ name="f_j",unicode={ 0x66,0x6A } }, - fk={ name="f_k",unicode={ 0x66,0x6B } }, - } - local o=allocate {} - for k,v in next,overloads do - local name=v.name - local mess=v.mess - if name then - o[name]=v - end - if mess then - o[mess]=v - end - o[k]=v - end - mappings.overloads=o -end -function mappings.addtounicode(data,filename,checklookups,forceligatures) - local resources=data.resources - local unicodes=resources.unicodes - if not unicodes then - if trace_mapping then - report_fonts("no unicode list, quitting tounicode for %a",filename) - end - return - end - local properties=data.properties - local descriptions=data.descriptions - local overloads=mappings.overloads - unicodes['space']=unicodes['space'] or 32 - unicodes['hyphen']=unicodes['hyphen'] or 45 - unicodes['zwj']=unicodes['zwj'] or 0x200D - unicodes['zwnj']=unicodes['zwnj'] or 0x200C - local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 - local unicodevector=fonts.encodings.agl.unicodes or {} - local contextvector=fonts.encodings.agl.ctxcodes or {} - local missing={} - local nofmissing=0 - local oparser=nil - local cidnames=nil - local cidcodes=nil - local cidinfo=properties.cidinfo - local usedmap=cidinfo and fonts.cid.getmap(cidinfo) - local uparser=makenameparser() - if usedmap then - oparser=usedmap and makenameparser(cidinfo.ordering) - cidnames=usedmap.names - cidcodes=usedmap.unicodes - end - local ns=0 - local nl=0 - local dlist=sortedkeys(descriptions) - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name - if name then - local overload=overloads[name] or overloads[du] - if overload then - glyph.unicode=overload.unicode - else - local gu=glyph.unicode - if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then - local unicode=unicodevector[name] or contextvector[name] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - if (not unicode) and usedmap then - local foundindex=lpegmatch(oparser,name) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - else - local reference=cidnames[foundindex] - if reference then - local foundindex=lpegmatch(oparser,reference) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,reference) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - end - end - end - end - if not unicode or unicode=="" then - local split=lpegmatch(namesplitter,name) - local nsplit=split and #split or 0 - if nsplit==0 then - elseif nsplit==1 then - local base=split[1] - local u=unicodes[base] or unicodevector[base] or contextvector[name] - if not u then - elseif type(u)=="table" then - if u[1]=private then - break - end - n=n+1 - t[n]=u[1] - else - if u>=private then - break - end - n=n+1 - t[n]=u - end - end - if n>0 then - if n==1 then - unicode=t[1] - else - unicode=t - end - glyph.unicode=unicode - end - end - nl=nl+1 - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,name) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - local r=overloads[unicode] - if r then - unicode=r.unicode - glyph.unicode=unicode - end - if not unicode then - missing[du]=true - nofmissing=nofmissing+1 - end - else - end - end - else - local overload=overloads[du] - if overload then - glyph.unicode=overload.unicode - elseif not glyph.unicode then - missing[du]=true - nofmissing=nofmissing+1 - end - end - end - if type(checklookups)=="function" then - checklookups(data,missing,nofmissing) - end - local unicoded=0 - local collected=fonts.handlers.otf.readers.getcomponents(data) - local function resolve(glyph,u) - local n=#u - for i=1,n do - if u[i]>private then - n=0 - break - end - end - if n>0 then - if n>1 then - glyph.unicode=u - else - glyph.unicode=u[1] - end - unicoded=unicoded+1 - end - end - if not collected then - elseif forceligatures or force_ligatures then - for i=1,#dlist do - local du=dlist[i] - if du>=private or (du>=0xE000 and du<=0xF8FF) then - local u=collected[du] - if u then - resolve(descriptions[du],u) - end - end - end - else - for i=1,#dlist do - local du=dlist[i] - if du>=private or (du>=0xE000 and du<=0xF8FF) then - local glyph=descriptions[du] - if glyph.class=="ligature" and not glyph.unicode then - local u=collected[du] - if u then - resolve(glyph,u) - end - end - end - end - end - if trace_mapping and unicoded>0 then - report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) - end - if trace_mapping then - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name or "-" - local index=glyph.index or 0 - local unicode=glyph.unicode - if unicode then - if type(unicode)=="table" then - local unicodes={} - for i=1,#unicode do - unicodes[i]=formatters("%U",unicode[i]) - end - report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) - else - report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) - end - else - report_fonts("internal slot %U, name %a, unicode %U",index,name,du) - end - end - end - if trace_loading and (ns>0 or nl>0) then - report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc” 04fa0ffad5c51198c7c19462949f54ed] --- - -if not modules then modules={} end modules ['font-vfc']={ - version=1.001, - comment="companion to font-ini.mkiv and hand-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local select,type=select,type -local insert=table.insert -local fonts=fonts -local helpers=fonts.helpers -local setmetatableindex=table.setmetatableindex -local push={ "push" } -local pop={ "pop" } -local dummy={ "comment" } -function helpers.prependcommands(commands,...) - insert(commands,1,push) - for i=select("#",...),1,-1 do - local s=(select(i,...)) - if s then - insert(commands,1,s) - end - end - insert(commands,pop) - return commands -end -function helpers.appendcommands(commands,...) - insert(commands,1,push) - insert(commands,pop) - for i=1,select("#",...) do - local s=(select(i,...)) - if s then - insert(commands,s) - end - end - return commands -end -function helpers.prependcommandtable(commands,t) - insert(commands,1,push) - for i=#t,1,-1 do - local s=t[i] - if s then - insert(commands,1,s) - end - end - insert(commands,pop) - return commands -end -function helpers.appendcommandtable(commands,t) - insert(commands,1,push) - insert(commands,pop) - for i=1,#t do - local s=t[i] - if s then - insert(commands,s) - end - end - return commands -end -local char=setmetatableindex(function(t,k) - local v={ "slot",0,k } - t[k]=v - return v -end) -local right=setmetatableindex(function(t,k) - local v={ "right",k } - t[k]=v - return v -end) -local left=setmetatableindex(function(t,k) - local v={ "right",-k } - t[k]=v - return v -end) -local down=setmetatableindex(function(t,k) - local v={ "down",k } - t[k]=v - return v -end) -local up=setmetatableindex(function(t,k) - local v={ "down",-k } - t[k]=v - return v -end) -helpers.commands=utilities.storage.allocate { - char=char, - right=right, - left=left, - down=down, - up=up, - push=push, - pop=pop, - dummy=dummy, -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr” 7a2f7a9e9627b29158e1822ea3c650ab] --- - -if not modules then modules={} end modules ['font-otr']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub -local fullstrip=string.fullstrip -local floor,round=math.floor,math.round -local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt -local lpegmatch=lpeg.match -local rshift=bit32.rshift -local setmetatableindex=table.setmetatableindex -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local stripstring=string.nospaces -local utf16_to_utf8_be=utf.utf16_to_utf8_be -local report=logs.reporter("otf reader") -local report_cmap=logs.reporter("otf reader","cmap") -local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end) -local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end) -fonts=fonts or {} -local handlers=fonts.handlers or {} -fonts.handlers=handlers -local otf=handlers.otf or {} -handlers.otf=otf -local readers=otf.readers or {} -otf.readers=readers -local streamreader=utilities.files -local streamwriter=utilities.files -readers.streamreader=streamreader -readers.streamwriter=streamwriter -local openfile=streamreader.open -local closefile=streamreader.close -local setposition=streamreader.setposition -local skipshort=streamreader.skipshort -local readbytes=streamreader.readbytes -local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 -local readshort=streamreader.readinteger2 -local readlong=streamreader.readinteger4 -local readfixed=streamreader.readfixed4 -local read2dot14=streamreader.read2dot14 -local readfword=readshort -local readufword=readushort -local readoffset=readushort -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -function streamreader.readtag(f) - return lower(stripstring(readstring(f,4))) -end -local short=2 -local ushort=2 -local ulong=4 -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - openfile=streamreader.open - closefile=streamreader.close - setposition=streamreader.setposition - skipshort=streamreader.skipshort - readbytes=streamreader.readbytes - readstring=streamreader.readstring - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readuint=streamreader.readcardinal3 - readulong=streamreader.readcardinal4 - readshort=streamreader.readinteger2 - readlong=streamreader.readinteger4 - readfixed=streamreader.readfixed4 - read2dot14=streamreader.read2dot14 - readfword=readshort - readufword=readushort - readoffset=readushort - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable - function streamreader.readtag(f) - return lower(stripstring(readstring(f,4))) - end -end) -local function readlongdatetime(f) - local a,b,c,d,e,f,g,h=readbytes(f,8) - return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h -end -local tableversion=0.004 -readers.tableversion=tableversion -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local reservednames={ [0]="copyright", - "family", - "subfamily", - "uniqueid", - "fullname", - "version", - "postscriptname", - "trademark", - "manufacturer", - "designer", - "description", - "vendorurl", - "designerurl", - "license", - "licenseurl", - "reserved", - "typographicfamily", - "typographicsubfamily", - "compatiblefullname", - "sampletext", - "cidfindfontname", - "wwsfamily", - "wwssubfamily", - "lightbackgroundpalette", - "darkbackgroundpalette", - "variationspostscriptnameprefix", -} -local platforms={ [0]="unicode", - "macintosh", - "iso", - "windows", - "custom", -} -local encodings={ - unicode={ [0]="unicode 1.0 semantics", - "unicode 1.1 semantics", - "iso/iec 10646", - "unicode 2.0 bmp", - "unicode 2.0 full", - "unicode variation sequences", - "unicode full repertoire", - }, - macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", - "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", - "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", - "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", - "uninterpreted", - }, - iso={ [0]="7-bit ascii", - "iso 10646", - "iso 8859-1", - }, - windows={ [0]="symbol", - "unicode bmp", - "shiftjis", - "prc", - "big5", - "wansung", - "johab", - "reserved 7", - "reserved 8", - "reserved 9", - "unicode ucs-4", - }, - custom={ - } -} -local decoders={ - unicode={}, - macintosh={}, - iso={}, - windows={ - ["unicode semantics"]=utf16_to_utf8_be, - ["unicode bmp"]=utf16_to_utf8_be, - ["unicode full"]=utf16_to_utf8_be, - ["unicode 1.0 semantics"]=utf16_to_utf8_be, - ["unicode 1.1 semantics"]=utf16_to_utf8_be, - ["unicode 2.0 bmp"]=utf16_to_utf8_be, - ["unicode 2.0 full"]=utf16_to_utf8_be, - ["unicode variation sequences"]=utf16_to_utf8_be, - ["unicode full repertoire"]=utf16_to_utf8_be, - }, - custom={}, -} -local languages={ - unicode={ - [ 0]="english", - }, - macintosh={ - [ 0]="english", - }, - iso={}, - windows={ - [0x0409]="english - united states", - }, - custom={}, -} -local standardromanencoding={ [0]= - "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", - "numbersign","dollar","percent","ampersand","quotesingle","parenleft", - "parenright","asterisk","plus","comma","hyphen","period","slash", - "zero","one","two","three","four","five","six","seven","eight", - "nine","colon","semicolon","less","equal","greater","question","at", - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", - "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", - "backslash","bracketright","asciicircum","underscore","grave","a","b", - "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", - "r","s","t","u","v","w","x","y","z","braceleft","bar", - "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", - "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", - "adieresis","atilde","aring","ccedilla","eacute","egrave", - "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", - "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", - "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", - "section","bullet","paragraph","germandbls","registered","copyright", - "trademark","acute","dieresis","notequal","AE","Oslash","infinity", - "plusminus","lessequal","greaterequal","yen","mu","partialdiff", - "summation","product","pi","integral","ordfeminine","ordmasculine", - "Omega","ae","oslash","questiondown","exclamdown","logicalnot", - "radical","florin","approxequal","Delta","guillemotleft", - "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", - "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", - "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", - "fraction","currency","guilsinglleft","guilsinglright","fi","fl", - "daggerdbl","periodcentered","quotesinglbase","quotedblbase", - "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", - "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", - "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", - "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", - "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", - "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", - "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", - "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", - "dcroat", -} -local weights={ - [100]="thin", - [200]="extralight", - [300]="light", - [400]="normal", - [500]="medium", - [600]="semibold", - [700]="bold", - [800]="extrabold", - [900]="black", -} -local widths={ - [1]="ultracondensed", - [2]="extracondensed", - [3]="condensed", - [4]="semicondensed", - [5]="normal", - [6]="semiexpanded", - [7]="expanded", - [8]="extraexpanded", - [9]="ultraexpanded", -} -setmetatableindex(weights,function(t,k) - local r=floor((k+50)/100)*100 - local v=(r>900 and "black") or rawget(t,r) or "normal" - return v -end) -setmetatableindex(widths,function(t,k) - return "normal" -end) -local panoseweights={ - [ 0]="normal", - [ 1]="normal", - [ 2]="verylight", - [ 3]="light", - [ 4]="thin", - [ 5]="book", - [ 6]="medium", - [ 7]="demi", - [ 8]="bold", - [ 9]="heavy", - [10]="black", -} -local panosewidths={ - [ 0]="normal", - [ 1]="normal", - [ 2]="normal", - [ 3]="normal", - [ 4]="normal", - [ 5]="expanded", - [ 6]="condensed", - [ 7]="veryexpanded", - [ 8]="verycondensed", - [ 9]="monospaced", -} -local helpers={} -readers.helpers=helpers -local function gotodatatable(f,fontdata,tag,criterium) - if criterium and f then - local tables=fontdata.tables - if tables then - local datatable=tables[tag] - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - return tableoffset - end - else - report("no tables") - end - end -end -local function reportskippedtable(f,fontdata,tag,criterium) - if criterium and f then - local tables=fontdata.tables - if tables then - local datatable=tables[tag] - if datatable then - report("loading of table %a skipped",tag) - end - else - report("no tables") - end - end -end -local function setvariabledata(fontdata,tag,data) - local variabledata=fontdata.variabledata - if variabledata then - variabledata[tag]=data - else - fontdata.variabledata={ [tag]=data } - end -end -helpers.gotodatatable=gotodatatable -helpers.setvariabledata=setvariabledata -helpers.reportskippedtable=reportskippedtable -local platformnames={ - postscriptname=true, - fullname=true, - family=true, - subfamily=true, - typographicfamily=true, - typographicsubfamily=true, - compatiblefullname=true, -} -local platformextras={ - uniqueid=true, - version=true, - copyright=true, - license=true, - licenseurl=true, - manufacturer=true, - vendorurl=true, -} -function readers.name(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"name",true) - if tableoffset then - local format=readushort(f) - local nofnames=readushort(f) - local offset=readushort(f) - local start=tableoffset+offset - local namelists={ - unicode={}, - windows={}, - macintosh={}, - } - for i=1,nofnames do - local platform=platforms[readushort(f)] - if platform then - local namelist=namelists[platform] - if namelist then - local encoding=readushort(f) - local language=readushort(f) - local encodings=encodings[platform] - local languages=languages[platform] - if encodings and languages then - local encoding=encodings[encoding] - local language=languages[language] - if encoding and language then - local index=readushort(f) - local name=reservednames[index] - namelist[#namelist+1]={ - platform=platform, - encoding=encoding, - language=language, - name=name, - index=index, - length=readushort(f), - offset=start+readushort(f), - } - else - skipshort(f,3) - end - else - skipshort(f,3) - end - else - skipshort(f,5) - end - else - skipshort(f,5) - end - end - local names={} - local done={} - local extras={} - local function decoded(platform,encoding,content) - local decoder=decoders[platform] - if decoder then - decoder=decoder[encoding] - end - if decoder then - return decoder(content) - else - return content - end - end - local function filter(platform,e,l) - local namelist=namelists[platform] - for i=1,#namelist do - local name=namelist[i] - local nametag=name.name - local index=name.index - if not done[nametag or i] then - local encoding=name.encoding - local language=name.language - if (not e or encoding==e) and (not l or language==l) then - setposition(f,name.offset) - local content=decoded(platform,encoding,readstring(f,name.length)) - if nametag then - names[nametag]={ - content=content, - platform=platform, - encoding=encoding, - language=language, - } - end - extras[index]=content - done[nametag or i]=true - end - end - end - end - filter("windows","unicode bmp","english - united states") - filter("macintosh","roman","english") - filter("windows") - filter("macintosh") - filter("unicode") - fontdata.names=names - fontdata.extras=extras - if specification.platformnames then - local collected={} - local platformextras=specification.platformextras and platformextras - for platform,namelist in next,namelists do - local filtered=false - for i=1,#namelist do - local entry=namelist[i] - local name=entry.name - if platformnames[name] or (platformextras and platformextras[name]) then - setposition(f,entry.offset) - local content=decoded(platform,entry.encoding,readstring(f,entry.length)) - if filtered then - filtered[name]=content - else - filtered={ [name]=content } - end - end - end - if filtered then - collected[platform]=filtered - end - end - fontdata.platformnames=collected - end - else - fontdata.names={} - end -end -local validutf=lpeg.patterns.validutf8 -local function getname(fontdata,key) - local names=fontdata.names - if names then - local value=names[key] - if value then - local content=value.content - return lpegmatch(validutf,content) and content or nil - end - end -end -readers["os/2"]=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"os/2",true) - if tableoffset then - local version=readushort(f) - local windowsmetrics={ - version=version, - averagewidth=readshort(f), - weightclass=readushort(f), - widthclass=readushort(f), - fstype=readushort(f), - subscriptxsize=readshort(f), - subscriptysize=readshort(f), - subscriptxoffset=readshort(f), - subscriptyoffset=readshort(f), - superscriptxsize=readshort(f), - superscriptysize=readshort(f), - superscriptxoffset=readshort(f), - superscriptyoffset=readshort(f), - strikeoutsize=readshort(f), - strikeoutpos=readshort(f), - familyclass=readshort(f), - panose={ readbytes(f,10) }, - unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, - vendor=readstring(f,4), - fsselection=readushort(f), - firstcharindex=readushort(f), - lastcharindex=readushort(f), - typoascender=readshort(f), - typodescender=readshort(f), - typolinegap=readshort(f), - winascent=readushort(f), - windescent=readushort(f), - } - if version>=1 then - windowsmetrics.codepageranges={ readulong(f),readulong(f) } - end - if version>=2 then - windowsmetrics.xheight=readshort(f) - windowsmetrics.capheight=readshort(f) - windowsmetrics.defaultchar=readushort(f) - windowsmetrics.breakchar=readushort(f) - end - windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] - windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] - windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] - windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] - fontdata.windowsmetrics=windowsmetrics - else - fontdata.windowsmetrics={} - end -end -readers.head=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"head",true) - if tableoffset then - local version=readulong(f) - local fontversion=readulong(f) - local fontheader={ - version=version, - fontversion=number.to16dot16(fontversion), - fontversionnumber=fontversion, - checksum=readushort(f)*0x10000+readushort(f), - magic=readulong(f), - flags=readushort(f), - units=readushort(f), - created=readlongdatetime(f), - modified=readlongdatetime(f), - xmin=readshort(f), - ymin=readshort(f), - xmax=readshort(f), - ymax=readshort(f), - macstyle=readushort(f), - smallpixels=readushort(f), - directionhint=readshort(f), - indextolocformat=readshort(f), - glyphformat=readshort(f), - } - fontdata.fontheader=fontheader - else - fontdata.fontheader={} - end - fontdata.nofglyphs=0 -end -readers.hhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) - if tableoffset then - fontdata.horizontalheader={ - version=readulong(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvancewidth=readufword(f), - minleftsidebearing=readfword(f), - minrightsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.horizontalheader={ - nofmetrics=0, - } - end -end -readers.vhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) - if tableoffset then - fontdata.verticalheader={ - version=readulong(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvanceheight=readufword(f), - mintopsidebearing=readfword(f), - minbottomsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.verticalheader={ - nofmetrics=0, - } - end -end -readers.maxp=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) - if tableoffset then - local version=readulong(f) - local nofglyphs=readushort(f) - fontdata.nofglyphs=nofglyphs - if version==0x00005000 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - } - elseif version==0x00010000 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - points=readushort(f), - contours=readushort(f), - compositepoints=readushort(f), - compositecontours=readushort(f), - zones=readushort(f), - twilightpoints=readushort(f), - storage=readushort(f), - functiondefs=readushort(f), - instructiondefs=readushort(f), - stackelements=readushort(f), - sizeofinstructions=readushort(f), - componentelements=readushort(f), - componentdepth=readushort(f), - } - else - fontdata.maximumprofile={ - version=version, - nofglyphs=0, - } - end - end -end -readers.hmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) - if tableoffset then - local horizontalheader=fontdata.horizontalheader - local nofmetrics=horizontalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local width=0 - local leftsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - width=readshort(f) - leftsidebearing=readshort(f) - if width~=0 then - glyph.width=width - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if width~=0 then - glyph.width=width - end - end - end -end -readers.vmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) - if tableoffset then - local verticalheader=fontdata.verticalheader - local nofmetrics=verticalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local vheight=0 - local vdefault=verticalheader.ascender-verticalheader.descender - local topsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - vheight=readushort(f) - topsidebearing=readshort(f) - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - if topsidebearing~=0 then - glyph.tsb=topsidebearing - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - end - end -end -readers.vorg=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"vorg",specification.glyphs) -end -readers.post=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"post",true) - if tableoffset then - local version=readulong(f) - fontdata.postscript={ - version=version, - italicangle=round(1000*readfixed(f))/1000, - underlineposition=readfword(f), - underlinethickness=readfword(f), - monospaced=readulong(f), - minmemtype42=readulong(f), - maxmemtype42=readulong(f), - minmemtype1=readulong(f), - maxmemtype1=readulong(f), - } - if not specification.glyphs then - elseif version==0x00010000 then - for index=0,#standardromanencoding do - glyphs[index].name=standardromanencoding[index] - end - elseif version==0x00020000 then - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local indices={} - local names={} - local maxnames=0 - for i=0,nofglyphs-1 do - local nameindex=readushort(f) - if nameindex>=258 then - maxnames=maxnames+1 - nameindex=nameindex-257 - indices[nameindex]=i - else - glyphs[i].name=standardromanencoding[nameindex] - end - end - for i=1,maxnames do - local mapping=indices[i] - if not mapping then - report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") - break - else - local length=readbyte(f) - if length>0 then - glyphs[mapping].name=readstring(f,length) - else - report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") - break - end - end - end - end - else - fontdata.postscript={} - end -end -readers.cff=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"cff",specification.glyphs) -end -local formatreaders={} -local duplicatestoo=true -local sequence={ - { 3,1,4 }, - { 3,10,12 }, - { 0,3,4 }, - { 0,3,12 }, - { 0,1,4 }, - { 0,1,12 }, - { 0,0,6 }, - { 3,0,6 }, - { 3,0,4 }, - { 0,5,14 }, - { 0,4,12 }, - { 3,10,13 }, -} -local supported={} -for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - local p=supported[sp] - if not p then - p={} - supported[sp]=p - end - local e=p[se] - if not e then - e={} - p[se]=e - end - e[sf]=true -end -formatreaders[4]=function(f,fontdata,offset) - setposition(f,offset+2) - local length=readushort(f) - local language=readushort(f) - local nofsegments=readushort(f)/2 - skipshort(f,3) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofdone=0 - local endchars=readcardinaltable(f,nofsegments,ushort) - local reserved=readushort(f) - local startchars=readcardinaltable(f,nofsegments,ushort) - local deltas=readcardinaltable(f,nofsegments,ushort) - local offsets=readcardinaltable(f,nofsegments,ushort) - local size=(length-2*2-5*2-4*2*nofsegments)/2 - local indices=readcardinaltable(f,size-1,ushort) - for segment=1,nofsegments do - local startchar=startchars[segment] - local endchar=endchars[segment] - local offset=offsets[segment] - local delta=deltas[segment] - if startchar==0xFFFF and endchar==0xFFFF then - elseif startchar==0xFFFF and offset==0 then - elseif offset==0xFFFF then - elseif offset==0 then - if trace_cmap_details then - report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local index=(unicode+delta)%65536 - if index and index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - else - local shift=(segment-nofsegments+offset/2)-startchar - if trace_cmap_details then - report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local slot=shift+unicode - local index=indices[slot] - if index and index>0 then - index=(index+delta)%65536 - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - end - end - return nofdone -end -formatreaders[6]=function(f,fontdata,offset) - setposition(f,offset) - local format=readushort(f) - local length=readushort(f) - local language=readushort(f) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local start=readushort(f) - local count=readushort(f) - local stop=start+count-1 - local nofdone=0 - if trace_cmap_details then - report_cmap("format 6 from %C to %C",2,start,stop) - end - for unicode=start,stop do - local index=readushort(f) - if index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - end - if not mapping[index] then - mapping[index]=unicode - end - end - end - end - return nofdone -end -formatreaders[12]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if trace_cmap_details then - report_cmap("format 12 from %C to %C starts at index %i",first,last,index) - end - for unicode=first,last do - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - index=index+1 - end - end - return nofdone -end -formatreaders[13]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if first=privateoffset then - local limit=privateoffset-1 - report("format 13 from %C to %C pruned to %C",first,last,limit) - last=limit - end - for unicode=first,last do - list[unicode]=true - end - nofdone=nofdone+last-first+1 - else - report("format 13 from %C to %C ignored",first,last) - end - end - return nofdone -end -formatreaders[14]=function(f,fontdata,offset) - if offset and offset~=0 then - setposition(f,offset) - local format=readushort(f) - local length=readulong(f) - local nofrecords=readulong(f) - local records={} - local variants={} - local nofdone=0 - fontdata.variants=variants - for i=1,nofrecords do - records[i]={ - selector=readuint(f), - default=readulong(f), - other=readulong(f), - } - end - for i=1,nofrecords do - local record=records[i] - local selector=record.selector - local default=record.default - local other=record.other - local other=record.other - if other~=0 then - setposition(f,offset+other) - local mapping={} - local count=readulong(f) - for i=1,count do - mapping[readuint(f)]=readushort(f) - end - nofdone=nofdone+count - variants[selector]=mapping - end - end - return nofdone - else - return 0 - end -end -local function checkcmap(f,fontdata,records,platform,encoding,format) - local pdata=records[platform] - if not pdata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format) - end - return 0 - end - local edata=pdata[encoding] - if not edata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format) - end - return 0 - end - local fdata=edata[format] - if not fdata then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format) - end - return 0 - elseif type(fdata)~="number" then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format) - end - return 0 - end - edata[format]=true - local reader=formatreaders[format] - if not reader then - if trace_cmap_details then - report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format) - end - return 0 - end - local n=reader(f,fontdata,fdata) or 0 - if trace_cmap_details or trace_cmap then - local p=platforms[platform] - local e=encodings[p] - report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i", - platform,p,encoding,e and e[encoding] or "?",format,n) - end - return n -end -function readers.cmap(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - local records={} - local unicodecid=false - local variantcid=false - local variants={} - local duplicates=fontdata.duplicates or {} - fontdata.duplicates=duplicates - for i=1,noftables do - local platform=readushort(f) - local encoding=readushort(f) - local offset=readulong(f) - local record=records[platform] - if not record then - records[platform]={ - [encoding]={ - offsets={ offset }, - formats={}, - } - } - else - local subtables=record[encoding] - if not subtables then - record[encoding]={ - offsets={ offset }, - formats={}, - } - else - local offsets=subtables.offsets - offsets[#offsets+1]=offset - end - end - end - if trace_cmap then - report("found cmaps:") - end - for platform,record in sortedhash(records) do - local p=platforms[platform] - local e=encodings[p] - local sp=supported[platform] - local ps=p or "?" - if trace_cmap then - if sp then - report(" platform %i: %s",platform,ps) - else - report(" platform %i: %s (unsupported)",platform,ps) - end - end - for encoding,subtables in sortedhash(record) do - local se=sp and sp[encoding] - local es=e and e[encoding] or "?" - if trace_cmap then - if se then - report(" encoding %i: %s",encoding,es) - else - report(" encoding %i: %s (unsupported)",encoding,es) - end - end - local offsets=subtables.offsets - local formats=subtables.formats - for i=1,#offsets do - local offset=tableoffset+offsets[i] - setposition(f,offset) - formats[readushort(f)]=offset - end - record[encoding]=formats - if trace_cmap then - local list=sortedkeys(formats) - for i=1,#list do - if not (se and se[list[i]]) then - list[i]=list[i].." (unsupported)" - end - end - report(" formats: % t",list) - end - end - end - local ok=false - for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - if checkcmap(f,fontdata,records,sp,se,sf)>0 then - ok=true - end - end - if not ok then - report("no useable unicode cmap found") - end - fontdata.cidmaps={ - version=version, - noftables=noftables, - records=records, - } - else - fontdata.cidmaps={} - end -end -function readers.loca(f,fontdata,specification) - reportskippedtable(f,fontdata,"loca",specification.glyphs) -end -function readers.glyf(f,fontdata,specification) - reportskippedtable(f,fontdata,"glyf",specification.glyphs) -end -function readers.colr(f,fontdata,specification) - reportskippedtable(f,fontdata,"colr",specification.glyphs) -end -function readers.cpal(f,fontdata,specification) - reportskippedtable(f,fontdata,"cpal",specification.glyphs) -end -function readers.svg(f,fontdata,specification) - reportskippedtable(f,fontdata,"svg",specification.glyphs) -end -function readers.sbix(f,fontdata,specification) - reportskippedtable(f,fontdata,"sbix",specification.glyphs) -end -function readers.cbdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"cbdt",specification.glyphs) -end -function readers.cblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"cblc",specification.glyphs) -end -function readers.ebdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebdt",specification.glyphs) -end -function readers.ebsc(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebsc",specification.glyphs) -end -function readers.eblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"eblc",specification.glyphs) -end -function readers.kern(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - local kerns={} - local glyphs=fontdata.glyphs - for i=1,nofpairs do - local left=readushort(f) - local right=readushort(f) - local kern=readfword(f) - local glyph=glyphs[left] - local kerns=glyph.kerns - if kerns then - kerns[right]=kern - else - glyph.kerns={ [right]=kern } - end - end - elseif format==2 then - report("todo: kern classes") - else - report("todo: kerns") - end - end - end -end -function readers.gdef(f,fontdata,specification) - reportskippedtable(f,fontdata,"gdef",specification.details) -end -function readers.gsub(f,fontdata,specification) - reportskippedtable(f,fontdata,"gsub",specification.details) -end -function readers.gpos(f,fontdata,specification) - reportskippedtable(f,fontdata,"gpos",specification.details) -end -function readers.math(f,fontdata,specification) - reportskippedtable(f,fontdata,"math",specification.details) -end -local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) - local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata - local names=fontdata.names - local info=nil - if names then - local metrics=fontdata.windowsmetrics or {} - local postscript=fontdata.postscript or {} - local fontheader=fontdata.fontheader or {} - local cffinfo=fontdata.cffinfo or {} - local verticalheader=fontdata.verticalheader or {} - local filename=fontdata.filename - local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) - local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) - local fontname=getname(fontdata,"postscriptname") - local fullname=getname(fontdata,"fullname") - local family=getname(fontdata,"family") - local subfamily=getname(fontdata,"subfamily") - local familyname=getname(fontdata,"typographicfamily") - local subfamilyname=getname(fontdata,"typographicsubfamily") - local compatiblename=getname(fontdata,"compatiblefullname") - if rawfamilynames then - else - if not familyname then familyname=family end - if not subfamilyname then subfamilyname=subfamily end - end - if platformnames then - platformnames=fontdata.platformnames - end - if instancenames then - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata and variabledata.instances - if instances then - instancenames={} - for i=1,#instances do - instancenames[i]=lower(stripstring(instances[i].subfamily)) - end - else - instancenames=nil - end - else - instancenames=nil - end - end - info={ - subfontindex=fontdata.subfontindex or sub or 0, - version=getname(fontdata,"version"), - fontname=fontname, - fullname=fullname, - family=family, - subfamily=subfamily, - familyname=familyname, - subfamilyname=subfamilyname, - compatiblename=compatiblename, - weight=weight and lower(weight), - width=width and lower(width), - pfmweight=metrics.weightclass or 400, - pfmwidth=metrics.widthclass or 5, - panosewidth=metrics.panosewidth, - panoseweight=metrics.panoseweight, - italicangle=postscript.italicangle or 0, - units=fontheader.units or 0, - designsize=fontdata.designsize, - minsize=fontdata.minsize, - maxsize=fontdata.maxsize, - boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil, - monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", - averagewidth=metrics.averagewidth, - xheight=metrics.xheight, - capheight=metrics.capheight or fontdata.maxy, - ascender=metrics.typoascender, - descender=metrics.typodescender, - platformnames=platformnames or nil, - instancenames=instancenames or nil, - tableoffsets=fontdata.tableoffsets, - defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0) - } - if metricstoo then - local keys={ - "version", - "ascender","descender","linegap", - "maxadvancewidth","maxadvanceheight","maxextent", - "minbottomsidebearing","mintopsidebearing", - } - local h=fontdata.horizontalheader or {} - local v=fontdata.verticalheader or {} - if h then - local th={} - local tv={} - for i=1,#keys do - local key=keys[i] - th[key]=h[key] or 0 - tv[key]=v[key] or 0 - end - info.horizontalmetrics=th - info.verticalmetrics=tv - end - end - elseif n then - info={ - filename=fontdata.filename, - comment="there is no info for subfont "..n, - } - else - info={ - filename=fontdata.filename, - comment="there is no info", - } - end - return info -end -local function loadtables(f,specification,offset) - if offset then - setposition(f,offset) - end - local tables={} - local basename=file.basename(specification.filename) - local filesize=specification.filesize - local filetime=specification.filetime - local fontdata={ - filename=basename, - filesize=filesize, - filetime=filetime, - version=readstring(f,4), - noftables=readushort(f), - searchrange=readushort(f), - entryselector=readushort(f), - rangeshift=readushort(f), - tables=tables, - foundtables=false, - } - for i=1,fontdata.noftables do - local tag=lower(stripstring(readstring(f,4))) - local checksum=readushort(f)*0x10000+readushort(f) - local offset=readulong(f) - local length=readulong(f) - if offset+length>filesize then - report("bad %a table in file %a",tag,basename) - end - tables[tag]={ - checksum=checksum, - offset=offset, - length=length, - } - end - fontdata.foundtables=sortedkeys(tables) - if tables.cff or tables.cff2 then - fontdata.format="opentype" - else - fontdata.format="truetype" - end - return fontdata,tables -end -local function prepareglyps(fontdata) - local glyphs=setmetatableindex(function(t,k) - local v={ - index=k, - } - t[k]=v - return v - end) - fontdata.glyphs=glyphs - fontdata.mapping={} -end -local function readtable(tag,f,fontdata,specification,...) - local reader=readers[tag] - if reader then - reader(f,fontdata,specification,...) - end -end -local function readdata(f,offset,specification) - local fontdata,tables=loadtables(f,specification,offset) - if specification.glyphs then - prepareglyps(fontdata) - end - fontdata.temporary={} - readtable("name",f,fontdata,specification) - local askedname=specification.askedname - if askedname then - local fullname=getname(fontdata,"fullname") or "" - local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") - local foundname=gsub(fullname,"[^a-zA-Z0-9]","") - if lower(cleanname)~=lower(foundname) then - return - end - end - readtable("stat",f,fontdata,specification) - readtable("avar",f,fontdata,specification) - readtable("fvar",f,fontdata,specification) - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata.instances - local axis=variabledata.axis - if axis and (not instances or #instances==0) then - instances={} - variabledata.instances=instances - local function add(n,subfamily,value) - local values={} - for i=1,#axis do - local a=axis[i] - values[i]={ - axis=a.tag, - value=i==n and value or a.default, - } - end - instances[#instances+1]={ - subfamily=subfamily, - values=values, - } - end - for i=1,#axis do - local a=axis[i] - local tag=a.tag - add(i,"default"..tag,a.default) - add(i,"minimum"..tag,a.minimum) - add(i,"maximum"..tag,a.maximum) - end - end - end - if not specification.factors then - local instance=specification.instance - if type(instance)=="string" then - local factors=helpers.getfactors(fontdata,instance) - if factors then - specification.factors=factors - fontdata.factors=factors - fontdata.instance=instance - report("user instance: %s, factors: % t",instance,factors) - else - report("user instance: %s, bad factors",instance) - end - end - end - if not fontdata.factors then - if fontdata.variabledata then - local factors=helpers.getfactors(fontdata,true) - if factors then - specification.factors=factors - fontdata.factors=factors - end - else - end - end - readtable("os/2",f,fontdata,specification) - readtable("head",f,fontdata,specification) - readtable("maxp",f,fontdata,specification) - readtable("hhea",f,fontdata,specification) - readtable("vhea",f,fontdata,specification) - readtable("hmtx",f,fontdata,specification) - readtable("vmtx",f,fontdata,specification) - readtable("vorg",f,fontdata,specification) - readtable("post",f,fontdata,specification) - readtable("mvar",f,fontdata,specification) - readtable("hvar",f,fontdata,specification) - readtable("vvar",f,fontdata,specification) - readtable("gdef",f,fontdata,specification) - readtable("cff",f,fontdata,specification) - readtable("cff2",f,fontdata,specification) - readtable("cmap",f,fontdata,specification) - readtable("loca",f,fontdata,specification) - readtable("glyf",f,fontdata,specification) - readtable("colr",f,fontdata,specification) - readtable("cpal",f,fontdata,specification) - readtable("svg",f,fontdata,specification) - readtable("sbix",f,fontdata,specification) - readtable("cbdt",f,fontdata,specification) - readtable("cblc",f,fontdata,specification) - readtable("ebdt",f,fontdata,specification) - readtable("eblc",f,fontdata,specification) - readtable("kern",f,fontdata,specification) - readtable("gsub",f,fontdata,specification) - readtable("gpos",f,fontdata,specification) - readtable("math",f,fontdata,specification) - fontdata.locations=nil - fontdata.cidmaps=nil - fontdata.dictionaries=nil - if specification.tableoffsets then - fontdata.tableoffsets=tables - setmetatableindex(tables,{ - version=fontdata.version, - noftables=fontdata.noftables, - searchrange=fontdata.searchrange, - entryselector=fontdata.entryselector, - rangeshift=fontdata.rangeshift, - }) - end - return fontdata -end -local function loadfontdata(specification) - local filename=specification.filename - local fileattr=lfs.attributes(filename) - local filesize=fileattr and fileattr.size or 0 - local filetime=fileattr and fileattr.modification or 0 - local f=openfile(filename,true) - if not f then - report("unable to open %a",filename) - elseif filesize==0 then - report("empty file %a",filename) - closefile(f) - else - specification.filesize=filesize - specification.filetime=filetime - local version=readstring(f,4) - local fontdata=nil - if version=="OTTO" or version=="true" or version=="\0\1\0\0" then - fontdata=readdata(f,0,specification) - elseif version=="ttcf" then - local subfont=tonumber(specification.subfont) - local ttcversion=readulong(f) - local nofsubfonts=readulong(f) - local offsets=readcardinaltable(f,nofsubfonts,ulong) - if subfont then - if subfont>=1 and subfont<=nofsubfonts then - fontdata=readdata(f,offsets[subfont],specification) - else - report("no subfont %a in file %a",subfont,filename) - end - else - subfont=specification.subfont - if type(subfont)=="string" and subfont~="" then - specification.askedname=subfont - for i=1,nofsubfonts do - fontdata=readdata(f,offsets[i],specification) - if fontdata then - fontdata.subfontindex=i - report("subfont named %a has index %a",subfont,i) - break - end - end - if not fontdata then - report("no subfont named %a",subfont) - end - else - local subfonts={} - fontdata={ - filename=filename, - filesize=filesize, - filetime=filetime, - version=version, - subfonts=subfonts, - ttcversion=ttcversion, - nofsubfonts=nofsubfonts, - } - for i=1,nofsubfonts do - subfonts[i]=readdata(f,offsets[i],specification) - end - end - end - else - report("unknown version %a in file %a",version,filename) - end - closefile(f) - return fontdata or {} - end -end -local function loadfont(specification,n,instance) - if type(specification)=="string" then - specification={ - filename=specification, - info=true, - details=true, - glyphs=true, - shapes=true, - kerns=true, - variable=true, - globalkerns=true, - lookups=true, - subfont=n or true, - tounicode=false, - instance=instance - } - end - if specification.shapes or specification.lookups or specification.kerns then - specification.glyphs=true - end - if specification.glyphs then - specification.details=true - end - if specification.details then - specification.info=true - end - if specification.platformnames then - specification.platformnames=true - end - if specification.instance or instance then - specification.variable=true - specification.instance=specification.instance or instance - end - local function message(str) - report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) - end - local ok,result=xpcall(loadfontdata,message,specification) - if ok then - return result - end -end -function readers.loadshapes(filename,n,instance,streams) - local fontdata=loadfont { - filename=filename, - shapes=true, - streams=streams, - variable=true, - subfont=n, - instance=instance, - } - if fontdata then - for k,v in next,fontdata.glyphs do - v.class=nil - v.index=nil - v.math=nil - end - local names=fontdata.names - if names then - for k,v in next,names do - names[k]=fullstrip(v.content) - end - end - end - return fontdata and { - filename=filename, - format=fontdata.format, - glyphs=fontdata.glyphs, - units=fontdata.fontheader.units, - cffinfo=fontdata.cffinfo, - fontheader=fontdata.fontheader, - horizontalheader=fontdata.horizontalheader, - verticalheader=fontdata.verticalheader, - maximumprofile=fontdata.maximumprofile, - names=fontdata.names, - postscript=fontdata.postscript, - } or { - filename=filename, - format="unknown", - glyphs={}, - units=0, - } -end -function readers.loadfont(filename,n,instance) - local fontdata=loadfont { - filename=filename, - glyphs=true, - shapes=false, - lookups=true, - variable=true, - subfont=n, - instance=instance, - } - if fontdata then - return { - tableversion=tableversion, - creator="context mkiv", - size=fontdata.filesize, - time=fontdata.filetime, - glyphs=fontdata.glyphs, - descriptions=fontdata.descriptions, - format=fontdata.format, - goodies={}, - metadata=getinfo(fontdata,n,false,false,true,true), - properties={ - hasitalics=fontdata.hasitalics or false, - maxcolorclass=fontdata.maxcolorclass, - hascolor=fontdata.hascolor or false, - instance=fontdata.instance, - factors=fontdata.factors, - nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil, - }, - resources={ - filename=filename, - private=privateoffset, - duplicates=fontdata.duplicates or {}, - features=fontdata.features or {}, - sublookups=fontdata.sublookups or {}, - marks=fontdata.marks or {}, - markclasses=fontdata.markclasses or {}, - marksets=fontdata.marksets or {}, - sequences=fontdata.sequences or {}, - variants=fontdata.variants, - version=getname(fontdata,"version"), - cidinfo=fontdata.cidinfo, - mathconstants=fontdata.mathconstants, - colorpalettes=fontdata.colorpalettes, - svgshapes=fontdata.svgshapes, - pngshapes=fontdata.pngshapes, - variabledata=fontdata.variabledata, - foundtables=fontdata.foundtables, - }, - } - end -end -function readers.getinfo(filename,specification) - local subfont=nil - local platformnames=false - local rawfamilynames=false - local instancenames=true - local tableoffsets=false - if type(specification)=="table" then - subfont=tonumber(specification.subfont) - platformnames=specification.platformnames - rawfamilynames=specification.rawfamilynames - tableoffsets=specification.tableoffsets - else - subfont=tonumber(specification) - end - local fontdata=loadfont { - filename=filename, - details=true, - platformnames=platformnames, - instancenames=true, - tableoffsets=tableoffsets, - } - if fontdata then - local subfonts=fontdata.subfonts - if not subfonts then - return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) - elseif not subfont then - local info={} - for i=1,#subfonts do - info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) - end - return info - elseif subfont>=1 and subfont<=#subfonts then - return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) - else - return { - filename=filename, - comment="there is no subfont "..subfont.." in this file" - } - end - else - return { - filename=filename, - comment="the file cannot be opened for reading", - } - end -end -function readers.rehash(fontdata,hashmethod) - report("the %a helper is not yet implemented","rehash") -end -function readers.checkhash(fontdata) - report("the %a helper is not yet implemented","checkhash") -end -function readers.pack(fontdata,hashmethod) - report("the %a helper is not yet implemented","pack") -end -function readers.unpack(fontdata) - report("the %a helper is not yet implemented","unpack") -end -function readers.expand(fontdata) - report("the %a helper is not yet implemented","unpack") -end -function readers.compact(fontdata) - report("the %a helper is not yet implemented","compact") -end -local extenders={} -function readers.registerextender(extender) - extenders[#extenders+1]=extender -end -function readers.extend(fontdata) - for i=1,#extenders do - local extender=extenders[i] - local name=extender.name or "unknown" - local action=extender.action - if action then - action(fontdata) - end - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- - -if not modules then modules={} end modules ['font-oti']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lower=string.lower -local fonts=fonts -local constructors=fonts.constructors -local otf=constructors.handlers.otf -local otffeatures=constructors.features.otf -local registerotffeature=otffeatures.register -local otftables=otf.tables or {} -otf.tables=otftables -local allocate=utilities.storage.allocate -registerotffeature { - name="features", - description="initialization of feature handler", - default=true, -} -local function setmode(tfmdata,value) - if value then - tfmdata.properties.mode=lower(value) - end -end -otf.modeinitializer=setmode -local function setlanguage(tfmdata,value) - if value then - local cleanvalue=lower(value) - local languages=otftables and otftables.languages - local properties=tfmdata.properties - if not languages then - properties.language=cleanvalue - elseif languages[value] then - properties.language=cleanvalue - else - properties.language="dflt" - end - end -end -local function setscript(tfmdata,value) - if value then - local cleanvalue=lower(value) - local scripts=otftables and otftables.scripts - local properties=tfmdata.properties - if not scripts then - properties.script=cleanvalue - elseif scripts[value] then - properties.script=cleanvalue - else - properties.script="dflt" - end - end -end -registerotffeature { - name="mode", - description="mode", - initializers={ - base=setmode, - node=setmode, - plug=setmode, - } -} -registerotffeature { - name="language", - description="language", - initializers={ - base=setlanguage, - node=setlanguage, - plug=setlanguage, - } -} -registerotffeature { - name="script", - description="script", - initializers={ - base=setscript, - node=setscript, - plug=setscript, - } -} -otftables.featuretypes=allocate { - gpos_single="position", - gpos_pair="position", - gpos_cursive="position", - gpos_mark2base="position", - gpos_mark2ligature="position", - gpos_mark2mark="position", - gpos_context="position", - gpos_contextchain="position", - gsub_single="substitution", - gsub_multiple="substitution", - gsub_alternate="substitution", - gsub_ligature="substitution", - gsub_context="substitution", - gsub_contextchain="substitution", - gsub_reversecontextchain="substitution", - gsub_reversesub="substitution", -} -function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) - if featuretype=="position" then - local default=scripts.dflt - if default then - if autoscript=="position" or autoscript==true then - return default - else - report_otf("script feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=scripts.dflt - if default then - if autoscript=="substitution" or autoscript==true then - return default - end - end - end -end -function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) - if featuretype=="position" then - local default=languages.dflt - if default then - if autolanguage=="position" or autolanguage==true then - return default - else - report_otf("language feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=languages.dflt - if default then - if autolanguage=="substitution" or autolanguage==true then - return default - end - end - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott” 1249b7018dba80e080fc478a38aa6756] --- - -if not modules then modules={} end modules ["font-ott"]={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset -local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find -local sequenced=table.sequenced -local is_boolean=string.is_boolean -local setmetatableindex=table.setmetatableindex -local setmetatablenewindex=table.setmetatablenewindex -local allocate=utilities.storage.allocate -local fonts=fonts -local otf=fonts.handlers.otf -local otffeatures=otf.features -local tables=otf.tables or {} -otf.tables=tables -local statistics=otf.statistics or {} -otf.statistics=statistics -local scripts=allocate { - ["adlm"]="adlam", - ["aghb"]="caucasian albanian", - ["ahom"]="ahom", - ["arab"]="arabic", - ["armi"]="imperial aramaic", - ["armn"]="armenian", - ["avst"]="avestan", - ["bali"]="balinese", - ["bamu"]="bamum", - ["bass"]="bassa vah", - ["batk"]="batak", - ["beng"]="bengali", - ["bhks"]="bhaiksuki", - ["bng2"]="bengali variant 2", - ["bopo"]="bopomofo", - ["brah"]="brahmi", - ["brai"]="braille", - ["bugi"]="buginese", - ["buhd"]="buhid", - ["byzm"]="byzantine music", - ["cakm"]="chakma", - ["cans"]="canadian syllabics", - ["cari"]="carian", - ["cham"]="cham", - ["cher"]="cherokee", - ["copt"]="coptic", - ["cprt"]="cypriot syllabary", - ["cyrl"]="cyrillic", - ["dev2"]="devanagari variant 2", - ["deva"]="devanagari", - ["dogr"]="dogra", - ["dsrt"]="deseret", - ["dupl"]="duployan", - ["egyp"]="egyptian heiroglyphs", - ["elba"]="elbasan", - ["ethi"]="ethiopic", - ["geor"]="georgian", - ["gjr2"]="gujarati variant 2", - ["glag"]="glagolitic", - ["gong"]="gunjala gondi", - ["gonm"]="masaram gondi", - ["goth"]="gothic", - ["gran"]="grantha", - ["grek"]="greek", - ["gujr"]="gujarati", - ["gur2"]="gurmukhi variant 2", - ["guru"]="gurmukhi", - ["hang"]="hangul", - ["hani"]="cjk ideographic", - ["hano"]="hanunoo", - ["hatr"]="hatran", - ["hebr"]="hebrew", - ["hluw"]="anatolian hieroglyphs", - ["hmng"]="pahawh hmong", - ["hung"]="old hungarian", - ["ital"]="old italic", - ["jamo"]="hangul jamo", - ["java"]="javanese", - ["kali"]="kayah li", - ["kana"]="hiragana and katakana", - ["khar"]="kharosthi", - ["khmr"]="khmer", - ["khoj"]="khojki", - ["knd2"]="kannada variant 2", - ["knda"]="kannada", - ["kthi"]="kaithi", - ["lana"]="tai tham", - ["lao" ]="lao", - ["latn"]="latin", - ["lepc"]="lepcha", - ["limb"]="limbu", - ["lina"]="linear a", - ["linb"]="linear b", - ["lisu"]="lisu", - ["lyci"]="lycian", - ["lydi"]="lydian", - ["mahj"]="mahajani", - ["maka"]="makasar", - ["mand"]="mandaic and mandaean", - ["mani"]="manichaean", - ["marc"]="marchen", - ["math"]="mathematical alphanumeric symbols", - ["medf"]="medefaidrin", - ["mend"]="mende kikakui", - ["merc"]="meroitic cursive", - ["mero"]="meroitic hieroglyphs", - ["mlm2"]="malayalam variant 2", - ["mlym"]="malayalam", - ["modi"]="modi", - ["mong"]="mongolian", - ["mroo"]="mro", - ["mtei"]="meitei Mayek", - ["mult"]="multani", - ["musc"]="musical symbols", - ["mym2"]="myanmar variant 2", - ["mymr"]="myanmar", - ["narb"]="old north arabian", - ["nbat"]="nabataean", - ["newa"]="newa", - ["nko" ]='n"ko', - ["nshu"]="nüshu", - ["ogam"]="ogham", - ["olck"]="ol chiki", - ["orkh"]="old turkic and orkhon runic", - ["ory2"]="odia variant 2", - ["orya"]="oriya", - ["osge"]="osage", - ["osma"]="osmanya", - ["palm"]="palmyrene", - ["pauc"]="pau cin hau", - ["perm"]="old permic", - ["phag"]="phags-pa", - ["phli"]="inscriptional pahlavi", - ["phlp"]="psalter pahlavi", - ["phnx"]="phoenician", - ["plrd"]="miao", - ["prti"]="inscriptional parthian", - ["rjng"]="rejang", - ["rohg"]="hanifi rohingya", - ["runr"]="runic", - ["samr"]="samaritan", - ["sarb"]="old south arabian", - ["saur"]="saurashtra", - ["sgnw"]="sign writing", - ["shaw"]="shavian", - ["shrd"]="sharada", - ["sidd"]="siddham", - ["sind"]="khudawadi", - ["sinh"]="sinhala", - ["sogd"]="sogdian", - ["sogo"]="old sogdian", - ["sora"]="sora sompeng", - ["soyo"]="soyombo", - ["sund"]="sundanese", - ["sylo"]="syloti nagri", - ["syrc"]="syriac", - ["tagb"]="tagbanwa", - ["takr"]="takri", - ["tale"]="tai le", - ["talu"]="tai lu", - ["taml"]="tamil", - ["tang"]="tangut", - ["tavt"]="tai viet", - ["tel2"]="telugu variant 2", - ["telu"]="telugu", - ["tfng"]="tifinagh", - ["tglg"]="tagalog", - ["thaa"]="thaana", - ["thai"]="thai", - ["tibt"]="tibetan", - ["tirh"]="tirhuta", - ["tml2"]="tamil variant 2", - ["ugar"]="ugaritic cuneiform", - ["vai" ]="vai", - ["wara"]="warang citi", - ["xpeo"]="old persian cuneiform", - ["xsux"]="sumero-akkadian cuneiform", - ["yi" ]="yi", - ["zanb"]="zanabazar square", -} -local languages=allocate { - ["aba" ]="abaza", - ["abk" ]="abkhazian", - ["ach" ]="acholi", - ["acr" ]="achi", - ["ady" ]="adyghe", - ["afk" ]="afrikaans", - ["afr" ]="afar", - ["agw" ]="agaw", - ["aio" ]="aiton", - ["aka" ]="akan", - ["als" ]="alsatian", - ["alt" ]="altai", - ["amh" ]="amharic", - ["ang" ]="anglo-saxon", - ["apph"]="phonetic transcription—americanist conventions", - ["ara" ]="arabic", - ["arg" ]="aragonese", - ["ari" ]="aari", - ["ark" ]="rakhine", - ["asm" ]="assamese", - ["ast" ]="asturian", - ["ath" ]="athapaskan", - ["avr" ]="avar", - ["awa" ]="awadhi", - ["aym" ]="aymara", - ["azb" ]="torki", - ["aze" ]="azerbaijani", - ["bad" ]="badaga", - ["bad0"]="banda", - ["bag" ]="baghelkhandi", - ["bal" ]="balkar", - ["ban" ]="balinese", - ["bar" ]="bavarian", - ["bau" ]="baulé", - ["bbc" ]="batak toba", - ["bbr" ]="berber", - ["bch" ]="bench", - ["bcr" ]="bible cree", - ["bdy" ]="bandjalang", - ["bel" ]="belarussian", - ["bem" ]="bemba", - ["ben" ]="bengali", - ["bgc" ]="haryanvi", - ["bgq" ]="bagri", - ["bgr" ]="bulgarian", - ["bhi" ]="bhili", - ["bho" ]="bhojpuri", - ["bik" ]="bikol", - ["bil" ]="bilen", - ["bis" ]="bislama", - ["bjj" ]="kanauji", - ["bkf" ]="blackfoot", - ["bli" ]="baluchi", - ["blk" ]="pa'o karen", - ["bln" ]="balante", - ["blt" ]="balti", - ["bmb" ]="bambara (bamanankan)", - ["bml" ]="bamileke", - ["bos" ]="bosnian", - ["bpy" ]="bishnupriya manipuri", - ["bre" ]="breton", - ["brh" ]="brahui", - ["bri" ]="braj bhasha", - ["brm" ]="burmese", - ["brx" ]="bodo", - ["bsh" ]="bashkir", - ["bsk" ]="burushaski", - ["bti" ]="beti", - ["bts" ]="batak simalungun", - ["bug" ]="bugis", - ["byv" ]="medumba", - ["cak" ]="kaqchikel", - ["cat" ]="catalan", - ["cbk" ]="zamboanga chavacano", - ["cchn"]="chinantec", - ["ceb" ]="cebuano", - ["cgg" ]="chiga", - ["cha" ]="chamorro", - ["che" ]="chechen", - ["chg" ]="chaha gurage", - ["chh" ]="chattisgarhi", - ["chi" ]="chichewa (chewa, nyanja)", - ["chk" ]="chukchi", - ["chk0"]="chuukese", - ["cho" ]="choctaw", - ["chp" ]="chipewyan", - ["chr" ]="cherokee", - ["chu" ]="chuvash", - ["chy" ]="cheyenne", - ["cja" ]="western cham", - ["cjm" ]="eastern cham", - ["cmr" ]="comorian", - ["cop" ]="coptic", - ["cor" ]="cornish", - ["cos" ]="corsican", - ["cpp" ]="creoles", - ["cre" ]="cree", - ["crr" ]="carrier", - ["crt" ]="crimean tatar", - ["csb" ]="kashubian", - ["csl" ]="church slavonic", - ["csy" ]="czech", - ["ctg" ]="chittagonian", - ["cuk" ]="san blas kuna", - ["dan" ]="danish", - ["dar" ]="dargwa", - ["dax" ]="dayi", - ["dcr" ]="woods cree", - ["deu" ]="german", - ["dgo" ]="dogri", - ["dgr" ]="dogri", - ["dhg" ]="dhangu", - ["dhv" ]="divehi (dhivehi, maldivian)", - ["diq" ]="dimli", - ["div" ]="divehi (dhivehi, maldivian)", - ["djr" ]="zarma", - ["djr0"]="djambarrpuyngu", - ["dng" ]="dangme", - ["dnj" ]="dan", - ["dnk" ]="dinka", - ["dri" ]="dari", - ["duj" ]="dhuwal", - ["dun" ]="dungan", - ["dzn" ]="dzongkha", - ["ebi" ]="ebira", - ["ecr" ]="eastern cree", - ["edo" ]="edo", - ["efi" ]="efik", - ["ell" ]="greek", - ["emk" ]="eastern maninkakan", - ["eng" ]="english", - ["erz" ]="erzya", - ["esp" ]="spanish", - ["esu" ]="central yupik", - ["eti" ]="estonian", - ["euq" ]="basque", - ["evk" ]="evenki", - ["evn" ]="even", - ["ewe" ]="ewe", - ["fan" ]="french antillean", - ["fan0"]=" fang", - ["far" ]="persian", - ["fat" ]="fanti", - ["fin" ]="finnish", - ["fji" ]="fijian", - ["fle" ]="dutch (flemish)", - ["fmp" ]="fe’fe’", - ["fne" ]="forest nenets", - ["fon" ]="fon", - ["fos" ]="faroese", - ["fra" ]="french", - ["frc" ]="cajun french", - ["fri" ]="frisian", - ["frl" ]="friulian", - ["frp" ]="arpitan", - ["fta" ]="futa", - ["ful" ]="fulah", - ["fuv" ]="nigerian fulfulde", - ["gad" ]="ga", - ["gae" ]="scottish gaelic (gaelic)", - ["gag" ]="gagauz", - ["gal" ]="galician", - ["gar" ]="garshuni", - ["gaw" ]="garhwali", - ["gez" ]="ge'ez", - ["gih" ]="githabul", - ["gil" ]="gilyak", - ["gil0"]="kiribati (gilbertese)", - ["gkp" ]="kpelle (guinea)", - ["glk" ]="gilaki", - ["gmz" ]="gumuz", - ["gnn" ]="gumatj", - ["gog" ]="gogo", - ["gon" ]="gondi", - ["grn" ]="greenlandic", - ["gro" ]="garo", - ["gua" ]="guarani", - ["guc" ]="wayuu", - ["guf" ]="gupapuyngu", - ["guj" ]="gujarati", - ["guz" ]="gusii", - ["hai" ]="haitian (haitian creole)", - ["hal" ]="halam", - ["har" ]="harauti", - ["hau" ]="hausa", - ["haw" ]="hawaiian", - ["hay" ]="haya", - ["haz" ]="hazaragi", - ["hbn" ]="hammer-banna", - ["her" ]="herero", - ["hil" ]="hiligaynon", - ["hin" ]="hindi", - ["hma" ]="high mari", - ["hmn" ]="hmong", - ["hmo" ]="hiri motu", - ["hnd" ]="hindko", - ["ho" ]="ho", - ["hri" ]="harari", - ["hrv" ]="croatian", - ["hun" ]="hungarian", - ["hye" ]="armenian", - ["hye0"]="armenian east", - ["iba" ]="iban", - ["ibb" ]="ibibio", - ["ibo" ]="igbo", - ["ido" ]="ido", - ["ijo" ]="ijo languages", - ["ile" ]="interlingue", - ["ilo" ]="ilokano", - ["ina" ]="interlingua", - ["ind" ]="indonesian", - ["ing" ]="ingush", - ["inu" ]="inuktitut", - ["ipk" ]="inupiat", - ["ipph"]="phonetic transcription—ipa conventions", - ["iri" ]="irish", - ["irt" ]="irish traditional", - ["isl" ]="icelandic", - ["ism" ]="inari sami", - ["ita" ]="italian", - ["iwr" ]="hebrew", - ["jam" ]="jamaican creole", - ["jan" ]="japanese", - ["jav" ]="javanese", - ["jbo" ]="lojban", - ["jct" ]="krymchak", - ["jii" ]="yiddish", - ["jud" ]="ladino", - ["jul" ]="jula", - ["kab" ]="kabardian", - ["kab0"]="kabyle", - ["kac" ]="kachchi", - ["kal" ]="kalenjin", - ["kan" ]="kannada", - ["kar" ]="karachay", - ["kat" ]="georgian", - ["kaz" ]="kazakh", - ["kde" ]="makonde", - ["kea" ]="kabuverdianu (crioulo)", - ["keb" ]="kebena", - ["kek" ]="kekchi", - ["kge" ]="khutsuri georgian", - ["kha" ]="khakass", - ["khk" ]="khanty-kazim", - ["khm" ]="khmer", - ["khs" ]="khanty-shurishkar", - ["kht" ]="khamti shan", - ["khv" ]="khanty-vakhi", - ["khw" ]="khowar", - ["kik" ]="kikuyu (gikuyu)", - ["kir" ]="kirghiz (kyrgyz)", - ["kis" ]="kisii", - ["kiu" ]="kirmanjki", - ["kjd" ]="southern kiwai", - ["kjp" ]="eastern pwo karen", - ["kjz" ]="bumthangkha", - ["kkn" ]="kokni", - ["klm" ]="kalmyk", - ["kmb" ]="kamba", - ["kmn" ]="kumaoni", - ["kmo" ]="komo", - ["kms" ]="komso", - ["kmz" ]="khorasani turkic", - ["knr" ]="kanuri", - ["kod" ]="kodagu", - ["koh" ]="korean old hangul", - ["kok" ]="konkani", - ["kom" ]="komi", - ["kon" ]="kikongo", - ["kon0"]="kongo", - ["kop" ]="komi-permyak", - ["kor" ]="korean", - ["kos" ]="kosraean", - ["koz" ]="komi-zyrian", - ["kpl" ]="kpelle", - ["kri" ]="krio", - ["krk" ]="karakalpak", - ["krl" ]="karelian", - ["krm" ]="karaim", - ["krn" ]="karen", - ["krt" ]="koorete", - ["ksh" ]="kashmiri", - ["ksh0"]="ripuarian", - ["ksi" ]="khasi", - ["ksm" ]="kildin sami", - ["ksw" ]="s’gaw karen", - ["kua" ]="kuanyama", - ["kui" ]="kui", - ["kul" ]="kulvi", - ["kum" ]="kumyk", - ["kur" ]="kurdish", - ["kuu" ]="kurukh", - ["kuy" ]="kuy", - ["kyk" ]="koryak", - ["kyu" ]="western kayah", - ["lad" ]="ladin", - ["lah" ]="lahuli", - ["lak" ]="lak", - ["lam" ]="lambani", - ["lao" ]="lao", - ["lat" ]="latin", - ["laz" ]="laz", - ["lcr" ]="l-cree", - ["ldk" ]="ladakhi", - ["lez" ]="lezgi", - ["lij" ]="ligurian", - ["lim" ]="limburgish", - ["lin" ]="lingala", - ["lis" ]="lisu", - ["ljp" ]="lampung", - ["lki" ]="laki", - ["lma" ]="low mari", - ["lmb" ]="limbu", - ["lmo" ]="lombard", - ["lmw" ]="lomwe", - ["lom" ]="loma", - ["lrc" ]="luri", - ["lsb" ]="lower sorbian", - ["lsm" ]="lule sami", - ["lth" ]="lithuanian", - ["ltz" ]="luxembourgish", - ["lua" ]="luba-lulua", - ["lub" ]="luba-katanga", - ["lug" ]="ganda", - ["luh" ]="luyia", - ["luo" ]="luo", - ["lvi" ]="latvian", - ["mad" ]="madura", - ["mag" ]="magahi", - ["mah" ]="marshallese", - ["maj" ]="majang", - ["mak" ]="makhuwa", - ["mal" ]="malayalam reformed", - ["mam" ]="mam", - ["man" ]="mansi", - ["map" ]="mapudungun", - ["mar" ]="marathi", - ["maw" ]="marwari", - ["mbn" ]="mbundu", - ["mbo" ]="mbo", - ["mch" ]="manchu", - ["mcr" ]="moose cree", - ["mde" ]="mende", - ["mdr" ]="mandar", - ["men" ]="me'en", - ["mer" ]="meru", - ["mfa" ]="pattani malay", - ["mfe" ]="morisyen", - ["min" ]="minangkabau", - ["miz" ]="mizo", - ["mkd" ]="macedonian", - ["mkr" ]="makasar", - ["mkw" ]="kituba", - ["mle" ]="male", - ["mlg" ]="malagasy", - ["mln" ]="malinke", - ["mlr" ]="malayalam reformed", - ["mly" ]="malay", - ["mnd" ]="mandinka", - ["mng" ]="mongolian", - ["mni" ]="manipuri", - ["mnk" ]="maninka", - ["mnx" ]="manx", - ["moh" ]="mohawk", - ["mok" ]="moksha", - ["mol" ]="moldavian", - ["mon" ]="mon", - ["mor" ]="moroccan", - ["mos" ]="mossi", - ["mri" ]="maori", - ["mth" ]="maithili", - ["mts" ]="maltese", - ["mun" ]="mundari", - ["mus" ]="muscogee", - ["mwl" ]="mirandese", - ["mww" ]="hmong daw", - ["myn" ]="mayan", - ["mzn" ]="mazanderani", - ["nag" ]="naga-assamese", - ["nah" ]="nahuatl", - ["nan" ]="nanai", - ["nap" ]="neapolitan", - ["nas" ]="naskapi", - ["nau" ]="nauruan", - ["nav" ]="navajo", - ["ncr" ]="n-cree", - ["ndb" ]="ndebele", - ["ndc" ]="ndau", - ["ndg" ]="ndonga", - ["nds" ]="low saxon", - ["nep" ]="nepali", - ["new" ]="newari", - ["nga" ]="ngbaka", - ["ngr" ]="nagari", - ["nhc" ]="norway house cree", - ["nis" ]="nisi", - ["niu" ]="niuean", - ["nkl" ]="nyankole", - ["nko" ]="n'ko", - ["nld" ]="dutch", - ["noe" ]="nimadi", - ["nog" ]="nogai", - ["nor" ]="norwegian", - ["nov" ]="novial", - ["nsm" ]="northern sami", - ["nso" ]="sotho, northern", - ["nta" ]="northern tai", - ["nto" ]="esperanto", - ["nym" ]="nyamwezi", - ["nyn" ]="norwegian nynorsk", - ["nza" ]="mbembe tigon", - ["oci" ]="occitan", - ["ocr" ]="oji-cree", - ["ojb" ]="ojibway", - ["ori" ]="odia", - ["oro" ]="oromo", - ["oss" ]="ossetian", - ["paa" ]="palestinian aramaic", - ["pag" ]="pangasinan", - ["pal" ]="pali", - ["pam" ]="pampangan", - ["pan" ]="punjabi", - ["pap" ]="palpa", - ["pap0"]="papiamentu", - ["pas" ]="pashto", - ["pau" ]="palauan", - ["pcc" ]="bouyei", - ["pcd" ]="picard", - ["pdc" ]="pennsylvania german", - ["pgr" ]="polytonic greek", - ["phk" ]="phake", - ["pih" ]="norfolk", - ["pil" ]="filipino", - ["plg" ]="palaung", - ["plk" ]="polish", - ["pms" ]="piemontese", - ["pnb" ]="western panjabi", - ["poh" ]="pocomchi", - ["pon" ]="pohnpeian", - ["pro" ]="provencal", - ["ptg" ]="portuguese", - ["pwo" ]="western pwo karen", - ["qin" ]="chin", - ["quc" ]="k’iche’", - ["quh" ]="quechua (bolivia)", - ["quz" ]="quechua", - ["qvi" ]="quechua (ecuador)", - ["qwh" ]="quechua (peru)", - ["raj" ]="rajasthani", - ["rar" ]="rarotongan", - ["rbu" ]="russian buriat", - ["rcr" ]="r-cree", - ["rej" ]="rejang", - ["ria" ]="riang", - ["rif" ]="tarifit", - ["rit" ]="ritarungo", - ["rkw" ]="arakwal", - ["rms" ]="romansh", - ["rmy" ]="vlax romani", - ["rom" ]="romanian", - ["roy" ]="romany", - ["rsy" ]="rusyn", - ["rtm" ]="rotuman", - ["rua" ]="kinyarwanda", - ["run" ]="rundi", - ["rup" ]="aromanian", - ["rus" ]="russian", - ["sad" ]="sadri", - ["san" ]="sanskrit", - ["sas" ]="sasak", - ["sat" ]="santali", - ["say" ]="sayisi", - ["scn" ]="sicilian", - ["sco" ]="scots", - ["scs" ]="north slavey", - ["sek" ]="sekota", - ["sel" ]="selkup", - ["sga" ]="old irish", - ["sgo" ]="sango", - ["sgs" ]="samogitian", - ["shi" ]="tachelhit", - ["shn" ]="shan", - ["sib" ]="sibe", - ["sid" ]="sidamo", - ["sig" ]="silte gurage", - ["sks" ]="skolt sami", - ["sky" ]="slovak", - ["sla" ]="slavey", - ["slv" ]="slovenian", - ["sml" ]="somali", - ["smo" ]="samoan", - ["sna" ]="sena", - ["sna0"]="shona", - ["snd" ]="sindhi", - ["snh" ]="sinhala (sinhalese)", - ["snk" ]="soninke", - ["sog" ]="sodo gurage", - ["sop" ]="songe", - ["sot" ]="sotho, southern", - ["sqi" ]="albanian", - ["srb" ]="serbian", - ["srd" ]="sardinian", - ["srk" ]="saraiki", - ["srr" ]="serer", - ["ssl" ]="south slavey", - ["ssm" ]="southern sami", - ["stq" ]="saterland frisian", - ["suk" ]="sukuma", - ["sun" ]="sundanese", - ["sur" ]="suri", - ["sva" ]="svan", - ["sve" ]="swedish", - ["swa" ]="swadaya aramaic", - ["swk" ]="swahili", - ["swz" ]="swati", - ["sxt" ]="sutu", - ["sxu" ]="upper saxon", - ["syl" ]="sylheti", - ["syr" ]="syriac", - ["syre"]="estrangela syriac", - ["syrj"]="western syriac", - ["syrn"]="eastern syriac", - ["szl" ]="silesian", - ["tab" ]="tabasaran", - ["taj" ]="tajiki", - ["tam" ]="tamil", - ["tat" ]="tatar", - ["tcr" ]="th-cree", - ["tdd" ]="dehong dai", - ["tel" ]="telugu", - ["tet" ]="tetum", - ["tgl" ]="tagalog", - ["tgn" ]="tongan", - ["tgr" ]="tigre", - ["tgy" ]="tigrinya", - ["tha" ]="thai", - ["tht" ]="tahitian", - ["tib" ]="tibetan", - ["tiv" ]="tiv", - ["tkm" ]="turkmen", - ["tmh" ]="tamashek", - ["tmn" ]="temne", - ["tna" ]="tswana", - ["tne" ]="tundra nenets", - ["tng" ]="tonga", - ["tod" ]="todo", - ["tod0"]="toma", - ["tpi" ]="tok pisin", - ["trk" ]="turkish", - ["tsg" ]="tsonga", - ["tsj" ]="tshangla", - ["tua" ]="turoyo aramaic", - ["tul" ]="tulu", - ["tum" ]="tulu", - ["tuv" ]="tuvin", - ["tvl" ]="tuvalu", - ["twi" ]="twi", - ["tyz" ]="tày", - ["tzm" ]="tamazight", - ["tzo" ]="tzotzil", - ["udm" ]="udmurt", - ["ukr" ]="ukrainian", - ["umb" ]="umbundu", - ["urd" ]="urdu", - ["usb" ]="upper sorbian", - ["uyg" ]="uyghur", - ["uzb" ]="uzbek", - ["vec" ]="venetian", - ["ven" ]="venda", - ["vit" ]="vietnamese", - ["vol" ]="volapük", - ["vro" ]="võro", - ["wa" ]="wa", - ["wag" ]="wagdi", - ["war" ]="waray-waray", - ["wcr" ]="west-cree", - ["wel" ]="welsh", - ["wlf" ]="wolof", - ["wln" ]="walloon", - ["wtm" ]="mewati", - ["xbd" ]="lü", - ["xhs" ]="xhosa", - ["xjb" ]="minjangbal", - ["xkf" ]="khengkha", - ["xog" ]="soga", - ["xpe" ]="kpelle (liberia)", - ["yak" ]="sakha", - ["yao" ]="yao", - ["yap" ]="yapese", - ["yba" ]="yoruba", - ["ycr" ]="y-cree", - ["yic" ]="yi classic", - ["yim" ]="yi modern", - ["zea" ]="zealandic", - ["zgh" ]="standard morrocan tamazigh", - ["zha" ]="zhuang", - ["zhh" ]="chinese, hong kong sar", - ["zhp" ]="chinese phonetic", - ["zhs" ]="chinese simplified", - ["zht" ]="chinese traditional", - ["znd" ]="zande", - ["zul" ]="zulu", - ["zza" ]="zazaki", -} -local features=allocate { - ["aalt"]="access all alternates", - ["abvf"]="above-base forms", - ["abvm"]="above-base mark positioning", - ["abvs"]="above-base substitutions", - ["afrc"]="alternative fractions", - ["akhn"]="akhands", - ["blwf"]="below-base forms", - ["blwm"]="below-base mark positioning", - ["blws"]="below-base substitutions", - ["c2pc"]="petite capitals from capitals", - ["c2sc"]="small capitals from capitals", - ["calt"]="contextual alternates", - ["case"]="case-sensitive forms", - ["ccmp"]="glyph composition/decomposition", - ["cfar"]="conjunct form after ro", - ["cjct"]="conjunct forms", - ["clig"]="contextual ligatures", - ["cpct"]="centered cjk punctuation", - ["cpsp"]="capital spacing", - ["cswh"]="contextual swash", - ["curs"]="cursive positioning", - ["dflt"]="default processing", - ["dist"]="distances", - ["dlig"]="discretionary ligatures", - ["dnom"]="denominators", - ["dtls"]="dotless forms", - ["expt"]="expert forms", - ["falt"]="final glyph alternates", - ["fin2"]="terminal forms #2", - ["fin3"]="terminal forms #3", - ["fina"]="terminal forms", - ["flac"]="flattened accents over capitals", - ["frac"]="fractions", - ["fwid"]="full width", - ["half"]="half forms", - ["haln"]="halant forms", - ["halt"]="alternate half width", - ["hist"]="historical forms", - ["hkna"]="horizontal kana alternates", - ["hlig"]="historical ligatures", - ["hngl"]="hangul", - ["hojo"]="hojo kanji forms", - ["hwid"]="half width", - ["init"]="initial forms", - ["isol"]="isolated forms", - ["ital"]="italics", - ["jalt"]="justification alternatives", - ["jp04"]="jis2004 forms", - ["jp78"]="jis78 forms", - ["jp83"]="jis83 forms", - ["jp90"]="jis90 forms", - ["kern"]="kerning", - ["lfbd"]="left bounds", - ["liga"]="standard ligatures", - ["ljmo"]="leading jamo forms", - ["lnum"]="lining figures", - ["locl"]="localized forms", - ["ltra"]="left-to-right alternates", - ["ltrm"]="left-to-right mirrored forms", - ["mark"]="mark positioning", - ["med2"]="medial forms #2", - ["medi"]="medial forms", - ["mgrk"]="mathematical greek", - ["mkmk"]="mark to mark positioning", - ["mset"]="mark positioning via substitution", - ["nalt"]="alternate annotation forms", - ["nlck"]="nlc kanji forms", - ["nukt"]="nukta forms", - ["numr"]="numerators", - ["onum"]="old style figures", - ["opbd"]="optical bounds", - ["ordn"]="ordinals", - ["ornm"]="ornaments", - ["palt"]="proportional alternate width", - ["pcap"]="petite capitals", - ["pkna"]="proportional kana", - ["pnum"]="proportional figures", - ["pref"]="pre-base forms", - ["pres"]="pre-base substitutions", - ["pstf"]="post-base forms", - ["psts"]="post-base substitutions", - ["pwid"]="proportional widths", - ["qwid"]="quarter widths", - ["rand"]="randomize", - ["rclt"]="required contextual alternates", - ["rkrf"]="rakar forms", - ["rlig"]="required ligatures", - ["rphf"]="reph form", - ["rtbd"]="right bounds", - ["rtla"]="right-to-left alternates", - ["rtlm"]="right to left mirrored forms", - ["rvrn"]="required variation alternates", - ["ruby"]="ruby notation forms", - ["salt"]="stylistic alternates", - ["sinf"]="scientific inferiors", - ["size"]="optical size", - ["smcp"]="small capitals", - ["smpl"]="simplified forms", - ["ssty"]="script style", - ["stch"]="stretching glyph decomposition", - ["subs"]="subscript", - ["sups"]="superscript", - ["swsh"]="swash", - ["titl"]="titling", - ["tjmo"]="trailing jamo forms", - ["tnam"]="traditional name forms", - ["tnum"]="tabular figures", - ["trad"]="traditional forms", - ["twid"]="third widths", - ["unic"]="unicase", - ["valt"]="alternate vertical metrics", - ["vatu"]="vattu variants", - ["vert"]="vertical writing", - ["vhal"]="alternate vertical half metrics", - ["vjmo"]="vowel jamo forms", - ["vkna"]="vertical kana alternates", - ["vkrn"]="vertical kerning", - ["vpal"]="proportional alternate vertical metrics", - ["vrtr"]="vertical alternates for rotation", - ["vrt2"]="vertical rotation", - ["zero"]="slashed zero", - ["trep"]="traditional tex replacements", - ["tlig"]="traditional tex ligatures", - ["ss.."]="stylistic set ..", - ["cv.."]="character variant ..", - ["js.."]="justification ..", - ["dv.."]="devanagari ..", - ["ml.."]="malayalam ..", -} -local baselines=allocate { - ["hang"]="hanging baseline", - ["icfb"]="ideographic character face bottom edge baseline", - ["icft"]="ideographic character face tope edige baseline", - ["ideo"]="ideographic em-box bottom edge baseline", - ["idtp"]="ideographic em-box top edge baseline", - ["math"]="mathematical centered baseline", - ["romn"]="roman baseline" -} -tables.scripts=scripts -tables.languages=languages -tables.features=features -tables.baselines=baselines -local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end) -local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end) -local report_checks=logs.reporter("fonts","checks") -if otffeatures.features then - for k,v in next,otffeatures.features do - features[k]=v - end - otffeatures.features=features -end -local function swapped(h) - local r={} - for k,v in next,h do - r[gsub(v,"[^a-z0-9]","")]=k - end - return r -end -local verbosescripts=allocate(swapped(scripts )) -local verboselanguages=allocate(swapped(languages)) -local verbosefeatures=allocate(swapped(features )) -local verbosebaselines=allocate(swapped(baselines)) -local function resolve(t,k) - if k then - k=gsub(lower(k),"[^a-z0-9]","") - local v=rawget(t,k) - if v then - return v - end - end -end -setmetatableindex(verbosescripts,resolve) -setmetatableindex(verboselanguages,resolve) -setmetatableindex(verbosefeatures,resolve) -setmetatableindex(verbosebaselines,resolve) -setmetatableindex(scripts,function(t,k) - if k then - k=lower(k) - if k=="dflt" then - return k - end - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - v=rawget(t,v) - if v then - return v - elseif acceptscripts then - report_checks("registering extra script %a",k) - rawset(t,k,k) - return k - end - end - return "dflt" -end) -setmetatableindex(languages,function(t,k) - if k then - k=lower(k) - if k=="dflt" then - return k - end - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - v=rawget(t,v) - if v then - return v - elseif acceptlanguages then - report_checks("registering extra language %a",k) - rawset(t,k,k) - return k - end - end - return "dflt" -end) -if setmetatablenewindex then - setmetatablenewindex(languages,"ignore") - setmetatablenewindex(scripts,"ignore") - setmetatablenewindex(baselines,"ignore") -end -local function resolve(t,k) - if k then - k=lower(k) - local v=rawget(t,k) - if v then - return v - end - k=gsub(k," ","") - local v=rawget(t,k) - if v then - return v - end - local tag,dd=match(k,"(..)(%d+)") - if tag and dd then - local v=rawget(t,tag) - if v then - return v - else - local v=rawget(t,tag.."..") - if v then - return (gsub(v,"%.%.",tonumber(dd))) - end - end - end - end - return k -end -setmetatableindex(features,resolve) -local function assign(t,k,v) - if k and v then - v=lower(v) - rawset(t,k,v) - end -end -if setmetatablenewindex then - setmetatablenewindex(features,assign) -end -local checkers={ - rand=function(v) - return v==true and "random" or v - end -} -if not storage then - return -end -local usedfeatures=statistics.usedfeatures or {} -statistics.usedfeatures=usedfeatures -table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) -storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" ) -local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end -function otffeatures.normalize(features,wrap) - if features then - local h={} - for key,value in next,features do - local k=lower(key) - if k=="language" then - local v=gsub(lower(value),"[^a-z0-9]","") - h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" - elseif k=="script" then - local v=gsub(lower(value),"[^a-z0-9]","") - h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" - elseif k=="axis" then - h[k]=normalizedaxis(value) - else - local uk=usedfeatures[key] - local uv=uk[value] - if uv then - else - uv=tonumber(value) - if uv then - elseif type(value)=="string" then - local b=is_boolean(value) - if type(b)=="nil" then - if wrap and find(value,",") then - uv="{"..lower(value).."}" - else - uv=lower(value) - end - else - uv=b - end - elseif type(value)=="table" then - uv=sequenced(t,",") - else - uv=value - end - if not rawget(features,k) then - k=rawget(verbosefeatures,k) or k - end - local c=checkers[k] - if c then - uv=c(uv) or vc - end - uk[value]=uv - end - h[k]=uv - end - end - return h - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff” aa9038651d9fedd2b76cacd1f69fd742] --- - -if not modules then modules={} end modules ['font-cff']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub -local concat,remove,unpack=table.concat,table.remove,table.unpack -local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max -local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct -local lpegmatch=lpeg.match -local formatters=string.formatters -local bytetable=string.bytetable -local idiv=number.idiv -local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local readbytetable=streamreader.readbytetable -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - readstring=streamreader.readstring - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readuint=streamreader.readcardinal3 - readulong=streamreader.readcardinal4 - setposition=streamreader.setposition - getposition=streamreader.getposition - readbytetable=streamreader.readbytetable -end) -local setmetatableindex=table.setmetatableindex -local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) -local report=logs.reporter("otf reader","cff") -local parsedictionaries -local parsecharstring -local parsecharstrings -local resetcharstrings -local parseprivates -local startparsing -local stopparsing -local defaultstrings={ [0]= - ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", - "ampersand","quoteright","parenleft","parenright","asterisk","plus", - "comma","hyphen","period","slash","zero","one","two","three","four", - "five","six","seven","eight","nine","colon","semicolon","less", - "equal","greater","question","at","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", - "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", - "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", - "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", - "sterling","fraction","yen","florin","section","currency", - "quotesingle","quotedblleft","guillemotleft","guilsinglleft", - "guilsinglright","fi","fl","endash","dagger","daggerdbl", - "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", - "quotedblright","guillemotright","ellipsis","perthousand","questiondown", - "grave","acute","circumflex","tilde","macron","breve","dotaccent", - "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", - "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", - "dotlessi","lslash","oslash","oe","germandbls","onesuperior", - "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", - "onequarter","divide","brokenbar","degree","thorn","threequarters", - "twosuperior","registered","minus","eth","multiply","threesuperior", - "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", - "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", - "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", - "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", - "aacute","acircumflex","adieresis","agrave","aring","atilde", - "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", - "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", - "odieresis","ograve","otilde","scaron","uacute","ucircumflex", - "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", - "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", - "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", - "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", - "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", - "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", - "threequartersemdash","periodsuperior","questionsmall","asuperior", - "bsuperior","centsuperior","dsuperior","esuperior","isuperior", - "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", - "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", - "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", - "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", - "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", - "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", - "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", - "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", - "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", - "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", - "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", - "threeeighths","fiveeighths","seveneighths","onethird","twothirds", - "zerosuperior","foursuperior","fivesuperior","sixsuperior", - "sevensuperior","eightsuperior","ninesuperior","zeroinferior", - "oneinferior","twoinferior","threeinferior","fourinferior", - "fiveinferior","sixinferior","seveninferior","eightinferior", - "nineinferior","centinferior","dollarinferior","periodinferior", - "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", - "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", - "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", - "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", - "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", - "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", - "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", - "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", - "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", -} -local standardnames={ [0]= - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false, - "space","exclam","quotedbl","numbersign","dollar","percent", - "ampersand","quoteright","parenleft","parenright","asterisk","plus", - "comma","hyphen","period","slash","zero","one","two","three","four", - "five","six","seven","eight","nine","colon","semicolon","less", - "equal","greater","question","at","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", - "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", - "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", - "z","braceleft","bar","braceright","asciitilde",false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,false,false,false,false,false,false,false,false,"exclamdown", - "cent","sterling","fraction","yen","florin","section","currency", - "quotesingle","quotedblleft","guillemotleft","guilsinglleft", - "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", - "periodcentered",false,"paragraph","bullet","quotesinglbase", - "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", - false,"questiondown",false,"grave","acute","circumflex","tilde", - "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, - "hungarumlaut","ogonek","caron","emdash",false,false,false,false, - false,false,false,false,false,false,false,false,false,false,false, - false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", - "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", - false,false,false,"dotlessi",false,false,"lslash","oslash","oe", - "germandbls",false,false,false,false -} -local cffreaders={ - readbyte, - readushort, - readuint, - readulong, -} -directives.register("fonts.streamreader",function() - cffreaders={ - readbyte, - readushort, - readuint, - readulong, - } -end) -local function readheader(f) - local offset=getposition(f) - local major=readbyte(f) - local header={ - offset=offset, - major=major, - minor=readbyte(f), - size=readbyte(f), - } - if major==1 then - header.dsize=readbyte(f) - elseif major==2 then - header.dsize=readushort(f) - else - end - setposition(f,offset+header.size) - return header -end -local function readlengths(f,longcount) - local count=longcount and readulong(f) or readushort(f) - if count==0 then - return {} - end - local osize=readbyte(f) - local read=cffreaders[osize] - if not read then - report("bad offset size: %i",osize) - return {} - end - local lengths={} - local previous=read(f) - for i=1,count do - local offset=read(f) - local length=offset-previous - if length<0 then - report("bad offset: %i",length) - length=0 - end - lengths[i]=length - previous=offset - end - return lengths -end -local function readfontnames(f) - local names=readlengths(f) - for i=1,#names do - names[i]=readstring(f,names[i]) - end - return names -end -local function readtopdictionaries(f) - local dictionaries=readlengths(f) - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - return dictionaries -end -local function readstrings(f) - local lengths=readlengths(f) - local strings=setmetatableindex({},defaultstrings) - local index=#defaultstrings - for i=1,#lengths do - index=index+1 - strings[index]=readstring(f,lengths[i]) - end - return strings -end -do - local stack={} - local top=0 - local result={} - local strings={} - local p_single=P("\00")/function() - result.version=strings[stack[top]] or "unset" - top=0 - end+P("\01")/function() - result.notice=strings[stack[top]] or "unset" - top=0 - end+P("\02")/function() - result.fullname=strings[stack[top]] or "unset" - top=0 - end+P("\03")/function() - result.familyname=strings[stack[top]] or "unset" - top=0 - end+P("\04")/function() - result.weight=strings[stack[top]] or "unset" - top=0 - end+P("\05")/function() - result.fontbbox={ unpack(stack,1,4) } - top=0 - end+P("\06")/function() - result.bluevalues={ unpack(stack,1,top) } - top=0 - end+P("\07")/function() - result.otherblues={ unpack(stack,1,top) } - top=0 - end+P("\08")/function() - result.familyblues={ unpack(stack,1,top) } - top=0 - end+P("\09")/function() - result.familyotherblues={ unpack(stack,1,top) } - top=0 - end+P("\10")/function() - result.strhw=stack[top] - top=0 - end+P("\11")/function() - result.strvw=stack[top] - top=0 - end+P("\13")/function() - result.uniqueid=stack[top] - top=0 - end+P("\14")/function() - result.xuid=concat(stack,"",1,top) - top=0 - end+P("\15")/function() - result.charset=stack[top] - top=0 - end+P("\16")/function() - result.encoding=stack[top] - top=0 - end+P("\17")/function() - result.charstrings=stack[top] - top=0 - end+P("\18")/function() - result.private={ - size=stack[top-1], - offset=stack[top], - } - top=0 - end+P("\19")/function() - result.subroutines=stack[top] - top=0 - end+P("\20")/function() - result.defaultwidthx=stack[top] - top=0 - end+P("\21")/function() - result.nominalwidthx=stack[top] - top=0 - end -+P("\24")/function() - result.vstore=stack[top] - top=0 - end+P("\25")/function() - result.maxstack=stack[top] - top=0 - end - local p_double=P("\12")*( - P("\00")/function() - result.copyright=stack[top] - top=0 - end+P("\01")/function() - result.monospaced=stack[top]==1 and true or false - top=0 - end+P("\02")/function() - result.italicangle=stack[top] - top=0 - end+P("\03")/function() - result.underlineposition=stack[top] - top=0 - end+P("\04")/function() - result.underlinethickness=stack[top] - top=0 - end+P("\05")/function() - result.painttype=stack[top] - top=0 - end+P("\06")/function() - result.charstringtype=stack[top] - top=0 - end+P("\07")/function() - result.fontmatrix={ unpack(stack,1,6) } - top=0 - end+P("\08")/function() - result.strokewidth=stack[top] - top=0 - end+P("\09")/function() - result.bluescale=stack[top] - top=0 - end+P("\10")/function() - result.bluesnap=stack[top] - top=0 - end+P("\11")/function() - result.bluefuzz=stack[top] - top=0 - end+P("\12")/function() - result.stemsnaph={ unpack(stack,1,top) } - top=0 - end+P("\13")/function() - result.stemsnapv={ unpack(stack,1,top) } - top=0 - end+P("\20")/function() - result.syntheticbase=stack[top] - top=0 - end+P("\21")/function() - result.postscript=strings[stack[top]] or "unset" - top=0 - end+P("\22")/function() - result.basefontname=strings[stack[top]] or "unset" - top=0 - end+P("\21")/function() - result.basefontblend=stack[top] - top=0 - end+P("\30")/function() - result.cid.registry=strings[stack[top-2]] or "unset" - result.cid.ordering=strings[stack[top-1]] or "unset" - result.cid.supplement=stack[top] - top=0 - end+P("\31")/function() - result.cid.fontversion=stack[top] - top=0 - end+P("\32")/function() - result.cid.fontrevision=stack[top] - top=0 - end+P("\33")/function() - result.cid.fonttype=stack[top] - top=0 - end+P("\34")/function() - result.cid.count=stack[top] - top=0 - end+P("\35")/function() - result.cid.uidbase=stack[top] - top=0 - end+P("\36")/function() - result.cid.fdarray=stack[top] - top=0 - end+P("\37")/function() - result.cid.fdselect=stack[top] - top=0 - end+P("\38")/function() - result.cid.fontname=strings[stack[top]] or "unset" - top=0 - end - ) - local remap={ - ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", - ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1", - ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2", - ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3", - ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4", - ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5", - ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6", - ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7", - ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8", - ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9", - ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", - ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", - ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", - ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", - } - local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF") - local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n) - top=top+1 - stack[top]=tonumber(n) or 0 - end - local p_byte=C(R("\32\246"))/function(b0) - top=top+1 - stack[top]=byte(b0)-139 - end - local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=(byte(b0)-247)*256+byte(b1)+108 - end - local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=-(byte(b0)-251)*256-byte(b1)-108 - end - local p_short=P("\28")*C(1)*C(1)/function(b1,b2) - top=top+1 - local n=0x100*byte(b1)+byte(b2) - if n>=0x8000 then - stack[top]=n-0xFFFF-1 - else - stack[top]=n - end - end - local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) - top=top+1 - local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) - if n>=0x8000000 then - stack[top]=n-0xFFFFFFFF-1 - else - stack[top]=n - end - end - local p_unsupported=P(1)/function(detail) - top=0 - end - local p_dictionary=( - p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported - )^1 - parsedictionaries=function(data,dictionaries,version) - stack={} - strings=data.strings - if trace_charstrings then - report("charstring format %a",version) - end - for i=1,#dictionaries do - top=0 - result=version=="cff" and { - monospaced=false, - italicangle=0, - underlineposition=-100, - underlinethickness=50, - painttype=0, - charstringtype=2, - fontmatrix={ 0.001,0,0,0.001,0,0 }, - fontbbox={ 0,0,0,0 }, - strokewidth=0, - charset=0, - encoding=0, - cid={ - fontversion=0, - fontrevision=0, - fonttype=0, - count=8720, - } - } or { - charstringtype=2, - charset=0, - vstore=0, - cid={ - }, - } - lpegmatch(p_dictionary,dictionaries[i]) - dictionaries[i]=result - end - result={} - top=0 - stack={} - end - parseprivates=function(data,dictionaries) - stack={} - strings=data.strings - for i=1,#dictionaries do - local private=dictionaries[i].private - if private and private.data then - top=0 - result={ - forcebold=false, - languagegroup=0, - expansionfactor=0.06, - initialrandomseed=0, - subroutines=0, - defaultwidthx=0, - nominalwidthx=0, - cid={ - }, - } - lpegmatch(p_dictionary,private.data) - private.data=result - end - end - result={} - top=0 - stack={} - end - local x=0 - local y=0 - local width=false - local lsb=0 - local r=0 - local stems=0 - local globalbias=0 - local localbias=0 - local nominalwidth=0 - local defaultwidth=0 - local charset=false - local globals=false - local locals=false - local depth=1 - local xmin=0 - local xmax=0 - local ymin=0 - local ymax=0 - local checked=false - local keepcurve=false - local version=2 - local regions=false - local nofregions=0 - local region=false - local factors=false - local axis=false - local vsindex=0 - local justpass=false - local seacs={} - local procidx=nil - local function showstate(where) - report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) - end - local function showvalue(where,value,showstack) - if showstack then - report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) - else - report("%w%-10s : %s",depth*2,where,tostring(value)) - end - end - local function xymoveto() - if keepcurve then - r=r+1 - result[r]={ x,y,"m" } - end - if checked then - if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("rmoveto") - end - x=x+stack[top-1] - y=y+stack[top] - top=0 - xymoveto() - end - local function hmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("hmoveto") - end - x=x+stack[top] - top=0 - xmoveto() - end - local function vmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("vmoveto") - end - y=y+stack[top] - top=0 - ymoveto() - end - local function rlineto() - if trace_charstrings then - showstate("rlineto") - end - for i=1,top,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - top=0 - end - local function hlineto() - if trace_charstrings then - showstate("hlineto") - end - if top==1 then - x=x+stack[1] - xlineto() - else - local swap=true - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function vlineto() - if trace_charstrings then - showstate("vlineto") - end - if top==1 then - y=y+stack[1] - ylineto() - else - local swap=false - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function rrcurveto() - if trace_charstrings then - showstate("rrcurveto") - end - for i=1,top,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hhcurveto() - if trace_charstrings then - showstate("hhcurveto") - end - local s=1 - if top%2~=0 then - y=y+stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+stack[i] - local ay=y - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx+stack[i+3] - y=by - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function vvcurveto() - if trace_charstrings then - showstate("vvcurveto") - end - local s=1 - local d=0 - if top%2~=0 then - d=stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+d - local ay=y+stack[i] - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx - y=by+stack[i+3] - xycurveto(ax,ay,bx,by,x,y) - d=0 - end - top=0 - end - local function xxcurveto(swap) - local last=top%4~=0 and stack[top] - if last then - top=top-1 - end - for i=1,top,4 do - local ax,ay,bx,by - if swap then - ax=x+stack[i] - ay=y - bx=ax+stack[i+1] - by=ay+stack[i+2] - y=by+stack[i+3] - if last and i+3==top then - x=bx+last - else - x=bx - end - swap=false - else - ax=x - ay=y+stack[i] - bx=ax+stack[i+1] - by=ay+stack[i+2] - x=bx+stack[i+3] - if last and i+3==top then - y=by+last - else - y=by - end - swap=true - end - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hvcurveto() - if trace_charstrings then - showstate("hvcurveto") - end - xxcurveto(true) - end - local function vhcurveto() - if trace_charstrings then - showstate("vhcurveto") - end - xxcurveto(false) - end - local function rcurveline() - if trace_charstrings then - showstate("rcurveline") - end - for i=1,top-2,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - x=x+stack[top-1] - y=y+stack[top] - xylineto() - top=0 - end - local function rlinecurve() - if trace_charstrings then - showstate("rlinecurve") - end - if top>6 then - for i=1,top-6,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - end - local ax=x+stack[top-5] - local ay=y+stack[top-4] - local bx=ax+stack[top-3] - local by=ay+stack[top-2] - x=bx+stack[top-1] - y=by+stack[top] - xycurveto(ax,ay,bx,by,x,y) - top=0 - end - local function flex() - if trace_charstrings then - showstate("flex") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - x=ex+stack[11] - y=ey+stack[12] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function hflex() - if trace_charstrings then - showstate("hflex") - end - local ax=x+stack[1] - local ay=y - local bx=ax+stack[2] - local by=ay+stack[3] - local cx=bx+stack[4] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[5] - local dy=by - local ex=dx+stack[6] - local ey=y - x=ex+stack[7] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function hflex1() - if trace_charstrings then - showstate("hflex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[6] - local dy=by - local ex=dx+stack[7] - local ey=dy+stack[8] - x=ex+stack[9] - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function flex1() - if trace_charstrings then - showstate("flex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - if abs(ex-x)>abs(ey-y) then - x=ex+stack[11] - else - y=ey+stack[11] - end - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function getstem() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate("stem") - end - stems=stems+idiv(top,2) - top=0 - end - local function getmask() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate(operator==19 and "hintmark" or "cntrmask") - end - stems=stems+idiv(top,2) - top=0 - if stems==0 then - elseif stems<=8 then - return 1 - else - return idiv(stems+7,8) - end - end - local function unsupported(t) - if trace_charstrings then - showstate("unsupported "..t) - end - top=0 - end - local function unsupportedsub(t) - if trace_charstrings then - showstate("unsupported sub "..t) - end - top=0 - end - local function getstem3() - if trace_charstrings then - showstate("stem3") - end - top=0 - end - local function divide() - if version=="cff" then - local d=stack[top] - top=top-1 - stack[top]=stack[top]/d - end - end - local function closepath() - if version=="cff" then - if trace_charstrings then - showstate("closepath") - end - end - top=0 - end - local function hsbw() - if version=="cff" then - if trace_charstrings then - showstate("hsbw") - end - lsb=stack[top-1] or 0 - width=stack[top] - end - top=0 - end - local function sbw() - if version=="cff" then - if trace_charstrings then - showstate("sbw") - end - lsb=stack[top-3] - width=stack[top-1] - end - top=0 - end - local function seac() - if version=="cff" then - if trace_charstrings then - showstate("seac") - end - end - top=0 - end - local popped=3 - local hints=3 - local function callothersubr() - if version=="cff" then - if trace_charstrings then - showstate("callothersubr") - end - if stack[top]==hints then - popped=stack[top-2] - else - popped=3 - end - local t=stack[top-1] - if t then - top=top-(t+2) - if top<0 then - top=0 - end - else - top=0 - end - else - top=0 - end - end - local function pop() - if version=="cff" then - if trace_charstrings then - showstate("pop") - end - top=top+1 - stack[top]=popped - else - top=0 - end - end - local function setcurrentpoint() - if version=="cff" then - if trace_charstrings then - showstate("setcurrentpoint (unsupported)") - end - x=x+stack[top-1] - y=y+stack[top] - end - top=0 - end - local reginit=false - local function updateregions(n) - if regions then - local current=regions[n] or regions[1] - nofregions=#current - if axis and n~=reginit then - factors={} - for i=1,nofregions do - local region=current[i] - local s=1 - for j=1,#axis do - local f=axis[j] - local r=region[j] - local start=r.start - local peak=r.peak - local stop=r.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - factors[i]=s - end - end - end - reginit=n - end - local function setvsindex() - local vsindex=stack[top] - if trace_charstrings then - showstate(formatters["vsindex %i"](vsindex)) - end - updateregions(vsindex) - top=top-1 - end - local function blend() - local n=stack[top] - top=top-1 - if axis then - if trace_charstrings then - local t=top-nofregions*n - local m=t-n - for i=1,n do - local k=m+i - local d=m+n+(i-1)*nofregions - local old=stack[k] - local new=old - for r=1,nofregions do - new=new+stack[d+r]*factors[r] - end - stack[k]=new - showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) - end - top=t - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=v - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=v - d=d+nofregions - end - end - else - top=top-nofregions*n - end - end - local actions={ [0]=unsupported, - getstem, - unsupported, - getstem, - vmoveto, - rlineto, - hlineto, - vlineto, - rrcurveto, - unsupported, - unsupported, - unsupported, - unsupported, - hsbw, - unsupported, - setvsindex, - blend, - unsupported, - getstem, - getmask, - getmask, - rmoveto, - hmoveto, - getstem, - rcurveline, - rlinecurve, - vvcurveto, - hhcurveto, - unsupported, - unsupported, - vhcurveto, - hvcurveto, - } - local reverse={ [0]="unsupported", - "getstem", - "unsupported", - "getstem", - "vmoveto", - "rlineto", - "hlineto", - "vlineto", - "rrcurveto", - "unsupported", - "unsupported", - "unsupported", - "unsupported", - "hsbw", - "unsupported", - "setvsindex", - "blend", - "unsupported", - "getstem", - "getmask", - "getmask", - "rmoveto", - "hmoveto", - "getstem", - "rcurveline", - "rlinecurve", - "vvcurveto", - "hhcurveto", - "unsupported", - "unsupported", - "vhcurveto", - "hvcurveto", - } - local subactions={ - [000]=dotsection, - [001]=getstem3, - [002]=getstem3, - [006]=seac, - [007]=sbw, - [012]=divide, - [016]=callothersubr, - [017]=pop, - [033]=setcurrentpoint, - [034]=hflex, - [035]=flex, - [036]=hflex1, - [037]=flex1, - } - local chars=setmetatableindex(function (t,k) - local v=char(k) - t[k]=v - return v - end) - local c_endchar=chars[14] - local encode={} - setmetatableindex(encode,function(t,i) - for i=-2048,-1130 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - for i=-1131,-108 do - local v=0xFB00-i-108 - t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=-107,107 do - t[i]=chars[i+139] - end - for i=108,1131 do - local v=0xF700+i-108 - t[i]=char(extract(v,8,8),extract(v,0,8)) - end - for i=1132,2048 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - setmetatableindex(encode,function(t,k) - local r=round(k) - local v=rawget(t,r) - if v then - return v - end - local v1=floor(k) - local v2=floor((k-v1)*0x10000) - return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) - end) - return t[i] - end) - readers.cffencoder=encode - local function p_setvsindex() - local vsindex=stack[top] - updateregions(vsindex) - top=top-1 - end - local function p_blend() - local n=stack[top] - top=top-1 - if not axis then - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=round(v) - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=round(v) - d=d+nofregions - end - end - end - local function p_getstem() - local n=0 - if top%2~=0 then - n=1 - end - if top>n then - stems=stems+idiv(top-n,2) - end - end - local function p_getmask() - local n=0 - if top%2~=0 then - n=1 - end - if top>n then - stems=stems+idiv(top-n,2) - end - if stems==0 then - return 0 - elseif stems<=8 then - return 1 - else - return idiv(stems+7,8) - end - end - local process - local function call(scope,list,bias) - depth=depth+1 - if top==0 then - showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) - top=0 - else - local index=stack[top]+bias - top=top-1 - if trace_charstrings then - showvalue(scope,index,true) - end - local tab=list[index] - if tab then - process(tab) - else - showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) - top=0 - end - end - depth=depth-1 - end - process=function(tab) - local i=1 - local n=#tab - while i<=n do - local t=tab[i] - if t>=32 then - top=top+1 - if t<=246 then - stack[top]=t-139 - i=i+1 - elseif t<=250 then - stack[top]=t*256-63124+tab[i+1] - i=i+2 - elseif t<=254 then - stack[top]=-t*256+64148-tab[i+1] - i=i+2 - else - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF - else - stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF - end - i=i+5 - end - elseif t==28 then - top=top+1 - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000 - else - stack[top]=n - end - i=i+3 - elseif t==11 then - if trace_charstrings then - showstate("return") - end - return - elseif t==10 then - call("local",locals,localbias) - i=i+1 - elseif t==14 then - if width then - elseif top>0 then - width=stack[1] - if trace_charstrings then - showvalue("width",width) - end - else - width=true - end - if trace_charstrings then - showstate("endchar") - end - return - elseif t==29 then - call("global",globals,globalbias) - i=i+1 - elseif t==12 then - i=i+1 - local t=tab[i] - if justpass then - if t>=34 and t<=37 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - r=r+1;result[r]=chars[12] - r=r+1;result[r]=chars[t] - top=0 - elseif t==6 then - seacs[procidx]={ - asb=stack[1], - adx=stack[2], - ady=stack[3], - base=stack[4], - accent=stack[5], - width=width, - lsb=lsb, - } - top=0 - else - local a=subactions[t] - if a then - a(t) - else - top=0 - end - end - else - local a=subactions[t] - if a then - a(t) - else - if trace_charstrings then - showvalue("",t) - end - top=0 - end - end - i=i+1 - elseif justpass then - if t==15 then - p_setvsindex() - i=i+1 - elseif t==16 then - local s=p_blend() or 0 - i=i+s+1 - elseif t==1 or t==3 or t==18 or operation==23 then - p_getstem() - if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - else - top=0 - end - i=i+1 - elseif t==19 or t==20 then - local s=p_getmask() or 0 - if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - for j=1,s do - i=i+1 - r=r+1;result[r]=chars[tab[i]] - end - else - i=i+s - top=0 - end - i=i+1 - elseif t==9 then - top=0 - i=i+1 - elseif t==13 then - hsbw() - if version=="cff" then - r=r+1;result[r]=encode[lsb] - r=r+1;result[r]=chars[22] - else - end - i=i+1 - else - if trace_charstrings then - showstate(reverse[t] or "") - end - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] - end - top=0 - end - r=r+1;result[r]=chars[t] - i=i+1 - end - else - local a=actions[t] - if a then - local s=a(t) - if s then - i=i+s+1 - else - i=i+1 - end - else - if trace_charstrings then - showstate(reverse[t] or "") - end - top=0 - i=i+1 - end - end - end - end - local function setbias(globals,locals,nobias) - if nobias then - return 0,0 - else - local g=#globals - local l=#locals - return - ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, - ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 - end - end - local function processshape(tab,index,hack) - if not tab then - glyphs[index]={ - boundingbox={ 0,0,0,0 }, - width=0, - name=charset and charset[index] or nil, - } - return - end - tab=bytetable(tab) - x=0 - y=0 - width=false - lsb=0 - r=0 - top=0 - stems=0 - result={} - popped=3 - procidx=index - xmin=0 - xmax=0 - ymin=0 - ymax=0 - checked=false - if trace_charstrings then - report("glyph: %i",index) - report("data : % t",tab) - end - if regions then - updateregions(vsindex) - end - process(tab) - if hack then - return x,y - end - local boundingbox={ - round(xmin), - round(ymin), - round(xmax), - round(ymax), - } - if width==true or width==false then - width=defaultwidth - else - width=nominalwidth+width - end - local glyph=glyphs[index] - if justpass then - r=r+1 - result[r]=c_endchar - local stream=concat(result) - if glyph then - glyph.stream=stream - else - glyphs[index]={ stream=stream } - end - elseif glyph then - glyph.segments=keepcurve~=false and result or nil - glyph.boundingbox=boundingbox - if not glyph.width then - glyph.width=width - end - if charset and not glyph.name then - glyph.name=charset[index] - end - elseif keepcurve then - glyphs[index]={ - segments=result, - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - else - glyphs[index]={ - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - end - if trace_charstrings then - report("width : %s",tostring(width)) - report("boundingbox: % t",boundingbox) - end - end - startparsing=function(fontdata,data,streams) - reginit=false - axis=false - regions=data.regions - justpass=streams==true - popped=3 - seacs={} - if regions then - regions={ regions } - axis=data.factors or false - end - end - stopparsing=function(fontdata,data) - stack={} - glyphs=false - result={} - top=0 - locals=false - globals=false - strings=false - popped=3 - seacs={} - end - local function setwidths(private) - if not private then - return 0,0 - end - local privatedata=private.data - if not privatedata then - return 0,0 - end - return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 - end - parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias) - local dictionary=data.dictionaries[1] - local charstrings=dictionary.charstrings - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=dictionary.charset - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - globalbias,localbias=setbias(globals,locals,nobias) - nominalwidth,defaultwidth=setwidths(dictionary.private) - if charstrings then - startparsing(fontdata,data,streams) - for index=1,#charstrings do - processshape(charstrings[index],index-1) - end - if justpass and next(seacs) then - local charset=data.dictionaries[1].charset - if charset then - local lookup=table.swapped(charset) - for index,v in next,seacs do - local bindex=lookup[standardnames[v.base]] - local aindex=lookup[standardnames[v.accent]] - local bglyph=bindex and glyphs[bindex] - local aglyph=aindex and glyphs[aindex] - if bglyph and aglyph then - local jp=justpass - justpass=false - local x,y=processshape(charstrings[bindex+1],bindex,true) - justpass=jp - local base=bglyph.stream - local accent=aglyph.stream - local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] - base=sub(base,1,#base-1) - glyphs[index].stream=base..moveto..accent - end - end - end - end - stopparsing(fontdata,data) - else - report("no charstrings") - end - return glyphs - end - parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=false - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - justpass=streams==true - seacs={} - globalbias,localbias=setbias(globals,locals,nobias) - nominalwidth,defaultwidth=setwidths(dictionary.private) - processshape(tab,index-1) - end -end -local function readglobals(f,data,version) - local routines=readlengths(f,version=="cff2") - for i=1,#routines do - routines[i]=readbytetable(f,routines[i]) - end - data.routines=routines -end -local function readencodings(f,data) - data.encodings={} -end -local function readcharsets(f,data,dictionary) - local header=data.header - local strings=data.strings - local nofglyphs=data.nofglyphs - local charsetoffset=dictionary.charset - if charsetoffset and charsetoffset~=0 then - setposition(f,header.offset+charsetoffset) - local format=readbyte(f) - local charset={ [0]=".notdef" } - dictionary.charset=charset - if format==0 then - for i=1,nofglyphs do - charset[i]=strings[readushort(f)] - end - elseif format==1 or format==2 then - local readcount=format==1 and readbyte or readushort - local i=1 - while i<=nofglyphs do - local sid=readushort(f) - local n=readcount(f) - for s=sid,sid+n do - charset[i]=strings[s] - i=i+1 - if i>nofglyphs then - break - end - end - end - else - report("cff parser: unsupported charset format %a",format) - end - else - dictionary.nocharset=true - dictionary.charset=nil - end -end -local function readprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries - local private=dictionaries[1].private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end -end -local function readlocals(f,data,dictionary,version) - local header=data.header - local private=dictionary.private - if private then - local subroutineoffset=private.data.subroutines - if subroutineoffset~=0 then - setposition(f,header.offset+private.offset+subroutineoffset) - local subroutines=readlengths(f,version=="cff2") - for i=1,#subroutines do - subroutines[i]=readbytetable(f,subroutines[i]) - end - dictionary.subroutines=subroutines - private.data.subroutines=nil - else - dictionary.subroutines={} - end - else - dictionary.subroutines={} - end -end -local function readcharstrings(f,data,version) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local stringtype=dictionary.charstringtype - local offset=dictionary.charstrings - if type(offset)~="number" then - elseif stringtype==2 then - setposition(f,header.offset+offset) - local charstrings=readlengths(f,version=="cff2") - local nofglyphs=#charstrings - for i=1,nofglyphs do - charstrings[i]=readstring(f,charstrings[i]) - end - data.nofglyphs=nofglyphs - dictionary.charstrings=charstrings - else - report("unsupported charstr type %i",stringtype) - data.nofglyphs=0 - dictionary.charstrings={} - end -end -local function readcidprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries[1].cid.dictionaries - for i=1,#dictionaries do - local dictionary=dictionaries[i] - local private=dictionary.private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end - end - parseprivates(data,dictionaries) -end -readers.parsecharstrings=parsecharstrings -local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local cid=not dictionary.private and dictionary.cid - readglobals(f,data,version) - readcharstrings(f,data,version) - if version=="cff2" then - dictionary.charset=nil - else - readencodings(f,data) - readcharsets(f,data,dictionary) - end - if cid then - local fdarray=cid.fdarray - if fdarray then - setposition(f,data.header.offset+fdarray) - local dictionaries=readlengths(f,version=="cff2") - local nofdictionaries=#dictionaries - if nofdictionaries>0 then - for i=1,nofdictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - dictionary.private=dictionaries[1].private - if nofdictionaries>1 then - report("ignoring dictionaries > 1 in cid font") - end - end - end - end - readprivates(f,data) - parseprivates(data,data.dictionaries) - readlocals(f,data,dictionary,version) - startparsing(fontdata,data,streams) - parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) - stopparsing(fontdata,data) -end -local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local cid=dictionary.cid - local cidselect=cid and cid.fdselect - readglobals(f,data,version) - readcharstrings(f,data,version) - if version~="cff2" then - readencodings(f,data) - end - local charstrings=dictionary.charstrings - local fdindex={} - local nofglyphs=data.nofglyphs - local maxindex=-1 - setposition(f,header.offset+cidselect) - local format=readbyte(f) - if format==1 then - for i=0,nofglyphs do - local index=readbyte(f) - fdindex[i]=index - if index>maxindex then - maxindex=index - end - end - elseif format==3 then - local nofranges=readushort(f) - local first=readushort(f) - local index=readbyte(f) - while true do - local last=readushort(f) - if index>maxindex then - maxindex=index - end - for i=first,last do - fdindex[i]=index - end - if last>=nofglyphs then - break - else - first=last+1 - index=readbyte(f) - end - end - else - end - if maxindex>=0 then - local cidarray=cid.fdarray - if cidarray then - setposition(f,header.offset+cidarray) - local dictionaries=readlengths(f,version=="cff2") - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - cid.dictionaries=dictionaries - readcidprivates(f,data) - for i=1,#dictionaries do - readlocals(f,data,dictionaries[i],version) - end - startparsing(fontdata,data,streams) - for i=1,#charstrings do - parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) - end - stopparsing(fontdata,data) - else - report("no cid array") - end - end -end -local gotodatatable=readers.helpers.gotodatatable -local function cleanup(data,dictionaries) -end -function readers.cff(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) - if tableoffset then - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local glyphs=fontdata.glyphs - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff") - local dic=dictionaries[1] - local cid=dic.cid - local cffinfo={ - familyname=dic.familyname, - fullname=dic.fullname, - boundingbox=dic.boundingbox, - weight=dic.weight, - italicangle=dic.italicangle, - underlineposition=dic.underlineposition, - underlinethickness=dic.underlinethickness, - defaultwidth=dic.defaultwidthx, - nominalwidth=dic.nominalwidthx, - monospaced=dic.monospaced, - } - fontdata.cidinfo=cid and { - registry=cid.registry, - ordering=cid.ordering, - supplement=cid.supplement, - } - fontdata.cffinfo=cffinfo - local all=specification.shapes or specification.streams or false - if specification.glyphs or all then - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) - else - readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) - end - end - local private=dic.private - if private then - local data=private.data - if type(data)=="table" then - cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth - cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth - cffinfo.bluevalues=data.bluevalues - cffinfo.otherblues=data.otherblues - cffinfo.familyblues=data.familyblues - cffinfo.familyotherblues=data.familyotherblues - cffinfo.bluescale=data.bluescale - cffinfo.blueshift=data.blueshift - cffinfo.bluefuzz=data.bluefuzz - cffinfo.stdhw=data.stdhw - cffinfo.stdvw=data.stdvw - end - end - cleanup(data,dictionaries) - end -end -function readers.cff2(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) - if tableoffset then - local header=readheader(f) - if header.major~=2 then - report("only version %s is supported for table %a",2,"cff2") - return - end - local glyphs=fontdata.glyphs - local dictionaries={ readstring(f,header.dsize) } - local data={ - header=header, - dictionaries=dictionaries, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff2") - local offset=dictionaries[1].vstore - if offset>0 then - local storeoffset=dictionaries[1].vstore+data.header.offset+2 - local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) - data.regions=regions - data.deltas=deltas - else - data.regions={} - data.deltas={} - end - data.factors=specification.factors - local cid=data.dictionaries[1].cid - local all=specification.shapes or specification.streams or false - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - else - readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - end - cleanup(data,dictionaries) - end -end -function readers.cffcheck(filename) - local f=io.open(filename,"rb") - if f then - local fontdata={ - glyphs={}, - } - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local glyphs={} - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - glyphs=glyphs, - nofglyphs=0, - } - parsedictionaries(data,dictionaries,"cff") - local cid=data.dictionaries[1].cid - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,false) - else - readnoselect(f,fontdata,data,glyphs,false) - end - return data - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf” 807599f6d56c775d53cf6f358d741f34] --- - -if not modules then modules={} end modules ['font-ttf']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,unpack=next,type,unpack -local band,rshift=bit32.band,bit32.rshift -local sqrt,round=math.sqrt,math.round -local char,rep=string.char,string.rep -local concat=table.concat -local idiv=number.idiv -local setmetatableindex=table.setmetatableindex -local report=logs.reporter("otf reader","ttf") -local trace_deltas=false -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local skipbytes=streamreader.skip -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 -local readchar=streamreader.readinteger1 -local readshort=streamreader.readinteger2 -local read2dot14=streamreader.read2dot14 -local readinteger=streamreader.readinteger1 -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - setposition=streamreader.setposition - getposition=streamreader.getposition - skipbytes=streamreader.skip - readbyte=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readulong=streamreader.readcardinal4 - readchar=streamreader.readinteger1 - readshort=streamreader.readinteger2 - read2dot14=streamreader.read2dot14 - readinteger=streamreader.readinteger1 - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable -end) -local short=2 -local ushort=2 -local ulong=4 -local helpers=readers.helpers -local gotodatatable=helpers.gotodatatable -local function mergecomposites(glyphs,shapes) - local function merge(index,shape,components) - local contours={} - local points={} - local nofcontours=0 - local nofpoints=0 - local offset=0 - local deltas=shape.deltas - for i=1,#components do - local component=components[i] - local subindex=component.index - local subshape=shapes[subindex] - local subcontours=subshape.contours - local subpoints=subshape.points - if not subcontours then - local subcomponents=subshape.components - if subcomponents then - subcontours,subpoints=merge(subindex,subshape,subcomponents) - end - end - if subpoints then - local matrix=component.matrix - local xscale=matrix[1] - local xrotate=matrix[2] - local yrotate=matrix[3] - local yscale=matrix[4] - local xoffset=matrix[5] - local yoffset=matrix[6] - local count=#subpoints - if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then - for i=1,count do - local p=subpoints[i] - nofpoints=nofpoints+1 - points[nofpoints]={ - p[1]+xoffset, - p[2]+yoffset, - p[3] - } - end - else - for i=1,count do - local p=subpoints[i] - local x=p[1] - local y=p[2] - nofpoints=nofpoints+1 - points[nofpoints]={ - xscale*x+xrotate*y+xoffset, - yscale*y+yrotate*x+yoffset, - p[3] - } - end - end - local subcount=#subcontours - if subcount==1 then - nofcontours=nofcontours+1 - contours[nofcontours]=offset+subcontours[1] - else - for i=1,#subcontours do - nofcontours=nofcontours+1 - contours[nofcontours]=offset+subcontours[i] - end - end - offset=offset+count - else - report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) - end - end - shape.points=points - shape.contours=contours - shape.components=nil - return contours,points - end - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local components=shape.components - if components then - merge(index,shape,components) - end - end - end -end -local function readnothing(f) - return { - type="nothing", - } -end -local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) - return - l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), - r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), - r_x,r_y,"c" -end -local function applyaxis(glyph,shape,deltas,dowidth) - local points=shape.points - if points then - local nofpoints=#points - local h=nofpoints+2 - local l=nofpoints+1 - local dw=0 - local dl=0 - for i=1,#deltas do - local deltaset=deltas[i] - local xvalues=deltaset.xvalues - local yvalues=deltaset.yvalues - local dpoints=deltaset.points - local factor=deltaset.factor - if dpoints then - local nofdpoints=#dpoints - for i=1,nofdpoints do - local d=dpoints[i] - local p=points[d] - if p then - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - elseif dowidth then - if d==h then - local x=xvalues[i] - if x then - dw=dw+factor*x - end - elseif d==l then - local x=xvalues[i] - if x then - dl=dl+factor*x - end - end - end - end - else - for i=1,nofpoints do - local p=points[i] - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - end - if dowidth then - local x=xvalues[h] - if x then - dw=dw+factor*x - end - local x=xvalues[l] - if x then - dl=dl+factor*x - end - end - end - end - if dowidth then - local width=glyph.width or 0 - glyph.width=width+dw-dl - end - else - report("no points for glyph %a",glyph.name) - end -end -local quadratic=false -local function contours2outlines_normal(glyphs,shapes) - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments={} - local nofsegments=0 - glyph.segments=segments - if nofcontours>0 then - local px=0 - local py=0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x=first_pt[1] - local y=first_pt[2] - if not done then - xmin=x - ymin=y - xmax=x - ymax=y - done=true - end - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - if not quadratic then - px=x - py=y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x,y=current_pt[1],current_pt[2] - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - if not quadratic then - px,py=x,y - end - else - control_pt=current_pt - end - elseif current_on then - local x1=control_pt[1] - local y1=control_pt[2] - local x2=current_pt[1] - local y2=current_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=false - else - local x2=(previous_pt[1]+current_pt[1])/2 - local y2=(previous_pt[2]+current_pt[2])/2 - local x1=control_pt[1] - local y1=control_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - else - nofsegments=nofsegments+1 - local x2=first_pt[1] - local y2=first_pt[2] - if not control_pt then - segments[nofsegments]={ x2,y2,"l" } - elseif quadratic then - local x1=control_pt[1] - local y1=control_pt[2] - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - local x1=control_pt[1] - local y1=control_pt[2] - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - first=last+1 - end - end - end - end - end -end -local function contours2outlines_shaped(glyphs,shapes,keepcurve) - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments=keepcurve and {} or nil - local nofsegments=0 - if keepcurve then - glyph.segments=segments - end - if nofcontours>0 then - local xmin,ymin,xmax,ymax,done=0,0,0,0,false - local px,py=0,0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - if keepcurve then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - end - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x=first_pt[1] - local y=first_pt[2] - if not done then - xmin,ymin,xmax,ymax=x,y,x,y - done=true - else - if xxmax then xmax=x end - if yymax then ymax=y end - end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - end - if not quadratic then - px=x - py=y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x=current_pt[1] - local y=current_pt[2] - if xxmax then xmax=x end - if yymax then ymax=y end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - end - if not quadratic then - px=x - py=y - end - else - control_pt=current_pt - end - elseif current_on then - local x1=control_pt[1] - local y1=control_pt[2] - local x2=current_pt[1] - local y2=current_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=false - else - local x2=(previous_pt[1]+current_pt[1])/2 - local y2=(previous_pt[2]+current_pt[2])/2 - local x1=control_pt[1] - local y1=control_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - elseif not control_pt then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ first_pt[1],first_pt[2],"l" } - end - else - local x1=control_pt[1] - local y1=control_pt[2] - local x2=first_pt[1] - local y2=first_pt[2] - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if quadratic then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - end - first=last+1 - end - glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } - end - end - end - end -end -local c_zero=char(0) -local s_zero=char(0,0) -local function toushort(n) - return char(band(rshift(n,8),0xFF),band(n,0xFF)) -end -local function toshort(n) - if n<0 then - n=n+0x10000 - end - return char(band(rshift(n,8),0xFF),band(n,0xFF)) -end -local chars=setmetatableindex(function(t,k) - for i=0,255 do local v=char(i) t[i]=v end return t[k] -end) -local function repackpoints(glyphs,shapes) - local noboundingbox={ 0,0,0,0 } - local result={} - local xpoints={} - local ypoints={} - for index=0,#glyphs-1 do - local shape=shapes[index] - if shape then - local r=0 - local glyph=glyphs[index] - local contours=shape.contours - local nofcontours=contours and #contours or 0 - local boundingbox=glyph.boundingbox or noboundingbox - r=r+1 result[r]=toshort(nofcontours) - r=r+1 result[r]=toshort(boundingbox[1]) - r=r+1 result[r]=toshort(boundingbox[2]) - r=r+1 result[r]=toshort(boundingbox[3]) - r=r+1 result[r]=toshort(boundingbox[4]) - if nofcontours>0 then - for i=1,nofcontours do - r=r+1 result[r]=toshort(contours[i]-1) - end - r=r+1 result[r]=s_zero - local points=shape.points - local currentx=0 - local currenty=0 - local x=0 - local y=0 - local lastflag=nil - local nofflags=0 - for i=1,#points do - local pt=points[i] - local px=pt[1] - local py=pt[2] - local fl=pt[3] and 0x01 or 0x00 - if px==currentx then - fl=fl+0x10 - else - local dx=round(px-currentx) - x=x+1 - if dx<-255 or dx>255 then - xpoints[x]=toshort(dx) - elseif dx<0 then - fl=fl+0x02 - xpoints[x]=chars[-dx] - elseif dx>0 then - fl=fl+0x12 - xpoints[x]=chars[dx] - else - fl=fl+0x02 - xpoints[x]=c_zero - end - end - if py==currenty then - fl=fl+0x20 - else - local dy=round(py-currenty) - y=y+1 - if dy<-255 or dy>255 then - ypoints[y]=toshort(dy) - elseif dy<0 then - fl=fl+0x04 - ypoints[y]=chars[-dy] - elseif dy>0 then - fl=fl+0x24 - ypoints[y]=chars[dy] - else - fl=fl+0x04 - ypoints[y]=c_zero - end - end - currentx=px - currenty=py - if lastflag==fl then - if nofflags==255 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - nofflags=1 - lastflag=fl - else - nofflags=nofflags+1 - end - else - if nofflags==1 then - r=r+1 result[r]=chars[lastflag] - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - nofflags=1 - lastflag=fl - end - end - if nofflags==1 then - r=r+1 result[r]=chars[lastflag] - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - r=r+1 result[r]=concat(xpoints,"",1,x) - r=r+1 result[r]=concat(ypoints,"",1,y) - end - local stream=concat(result,"",1,r) - local length=#stream - local padding=idiv(length+3,4)*4-length - if padding>0 then - if padding==1 then - padding="\0" - elseif padding==2 then - padding="\0\0" - else - padding="\0\0\0" - end - padding=stream..padding - end - glyph.stream=stream - end - end -end -local flags={} -local function readglyph(f,nofcontours) - local points={} - local contours={} - for i=1,nofcontours do - contours[i]=readshort(f)+1 - end - local nofpoints=contours[nofcontours] - local nofinstructions=readushort(f) - skipbytes(f,nofinstructions) - local i=1 - while i<=nofpoints do - local flag=readbyte(f) - flags[i]=flag - if band(flag,0x08)~=0 then - local n=readbyte(f) - if n==1 then - i=i+1 - flags[i]=flag - else - for j=1,n do - i=i+1 - flags[i]=flag - end - end - end - i=i+1 - end - local x=0 - for i=1,nofpoints do - local flag=flags[i] - if band(flag,0x02)~=0 then - if band(flag,0x10)~=0 then - x=x+readbyte(f) - else - x=x-readbyte(f) - end - elseif band(flag,0x10)~=0 then - else - x=x+readshort(f) - end - points[i]={ x,0,band(flag,0x01)~=0 } - end - local y=0 - for i=1,nofpoints do - local flag=flags[i] - if band(flag,0x04)~=0 then - if band(flag,0x20)~=0 then - y=y+readbyte(f) - else - y=y-readbyte(f) - end - elseif band(flag,0x20)~=0 then - else - y=y+readshort(f) - end - points[i][2]=y - end - return { - type="glyph", - points=points, - contours=contours, - nofpoints=nofpoints, - } -end -local function readcomposite(f) - local components={} - local nofcomponents=0 - local instructions=false - while true do - local flags=readushort(f) - local index=readushort(f) - local f_xyarg=band(flags,0x0002)~=0 - local f_offset=band(flags,0x0800)~=0 - local xscale=1 - local xrotate=0 - local yrotate=0 - local yscale=1 - local xoffset=0 - local yoffset=0 - local base=false - local reference=false - if f_xyarg then - if band(flags,0x0001)~=0 then - xoffset=readshort(f) - yoffset=readshort(f) - else - xoffset=readchar(f) - yoffset=readchar(f) - end - else - if band(flags,0x0001)~=0 then - base=readshort(f) - reference=readshort(f) - else - base=readchar(f) - reference=readchar(f) - end - end - if band(flags,0x0008)~=0 then - xscale=read2dot14(f) - yscale=xscale - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0040)~=0 then - xscale=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0080)~=0 then - xscale=read2dot14(f) - xrotate=read2dot14(f) - yrotate=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*sqrt(xscale^2+xrotate^2) - yoffset=yoffset*sqrt(yrotate^2+yscale^2) - end - end - nofcomponents=nofcomponents+1 - components[nofcomponents]={ - index=index, - usemine=band(flags,0x0200)~=0, - round=band(flags,0x0006)~=0, - base=base, - reference=reference, - matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, - } - if band(flags,0x0100)~=0 then - instructions=true - end - if band(flags,0x0020)==0 then - break - end - end - return { - type="composite", - components=components, - } -end -function readers.loca(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.loca - if datatable then - local offset=fontdata.tables.glyf.offset - local format=fontdata.fontheader.indextolocformat - local profile=fontdata.maximumprofile - local nofglyphs=profile and profile.nofglyphs - local locations={} - setposition(f,datatable.offset) - if format==1 then - if not nofglyphs then - nofglyphs=idiv(datatable.length,4)-1 - end - for i=0,nofglyphs do - locations[i]=offset+readulong(f) - end - fontdata.nofglyphs=nofglyphs - else - if not nofglyphs then - nofglyphs=idiv(datatable.length,2)-1 - end - for i=0,nofglyphs do - locations[i]=offset+readushort(f)*2 - end - end - fontdata.nofglyphs=nofglyphs - fontdata.locations=locations - end - end -end -function readers.glyf(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) - if tableoffset then - local locations=fontdata.locations - if locations then - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local filesize=fontdata.filesize - local nothing={ 0,0,0,0 } - local shapes={} - local loadshapes=specification.shapes or specification.instance or specification.streams - for index=0,nofglyphs-1 do - local location=locations[index] - local length=locations[index+1]-location - if location>=filesize then - report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) - fontdata.nofglyphs=index-1 - fontdata.badfont=true - break - elseif length>0 then - setposition(f,location) - local nofcontours=readshort(f) - glyphs[index].boundingbox={ - readshort(f), - readshort(f), - readshort(f), - readshort(f), - } - if not loadshapes then - elseif nofcontours==0 then - shapes[index]=readnothing(f) - elseif nofcontours>0 then - shapes[index]=readglyph(f,nofcontours) - else - shapes[index]=readcomposite(f,nofcontours) - end - else - if loadshapes then - shapes[index]=readnothing(f) - end - glyphs[index].boundingbox=nothing - end - end - if loadshapes then - if readers.gvar then - readers.gvar(f,fontdata,specification,glyphs,shapes) - end - mergecomposites(glyphs,shapes) - if specification.instance then - if specification.streams then - repackpoints(glyphs,shapes) - else - contours2outlines_shaped(glyphs,shapes,specification.shapes) - end - elseif specification.shapes then - if specification.streams then - repackpoints(glyphs,shapes) - else - contours2outlines_normal(glyphs,shapes) - end - elseif specification.streams then - repackpoints(glyphs,shapes) - end - end - end - end -end -local function readtuplerecord(f,nofaxis) - local record={} - for i=1,nofaxis do - record[i]=read2dot14(f) - end - return record -end -local function readpoints(f) - local count=readbyte(f) - if count==0 then - return nil,0 - else - if count<128 then - elseif band(count,0x80)~=0 then - count=band(count,0x7F)*256+readbyte(f) - else - end - local points={} - local p=0 - local n=1 - while p0 do - local control=readbyte(f) -if not control then - break -end - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - z=z+runlength - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - if z>0 then - for i=1,z do - p=p+1 - deltas[p]=0 - end - z=0 - end - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - end - if p>0 then - return deltas - else - end -end -local function readdeltas(f,nofpoints) - local deltas={} - local p=0 - while nofpoints>0 do - local control=readbyte(f) - if control then - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - for i=1,runlength do - p=p+1 - deltas[p]=0 - end - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - else - break - end - end - if p>0 then - return deltas - else - end -end -function readers.gvar(f,fontdata,specification,glyphdata,shapedata) - local instance=specification.instance - if not instance then - return - end - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) - if tableoffset then - local version=readulong(f) - local nofaxis=readushort(f) - local noftuples=readushort(f) - local tupleoffset=tableoffset+readulong(f) - local nofglyphs=readushort(f) - local flags=readushort(f) - local dataoffset=tableoffset+readulong(f) - local data={} - local tuples={} - local glyphdata=fontdata.glyphs - local dowidth=not fontdata.variabledata.hvarwidths - if band(flags,0x0001)~=0 then - for i=1,nofglyphs+1 do - data[i]=dataoffset+readulong(f) - end - else - for i=1,nofglyphs+1 do - data[i]=dataoffset+2*readushort(f) - end - end - if noftuples>0 then - setposition(f,tupleoffset) - for i=1,noftuples do - tuples[i]=readtuplerecord(f,nofaxis) - end - end - local nextoffset=false - local startoffset=data[1] - for i=1,nofglyphs do - nextoffset=data[i+1] - local glyph=glyphdata[i-1] - local name=trace_deltas and glyph.name - if startoffset==nextoffset then - if name then - report("no deltas for glyph %a",name) - end - else - local shape=shapedata[i-1] - if not shape then - if name then - report("no shape for glyph %a",name) - end - else - lastoffset=startoffset - setposition(f,startoffset) - local flags=readushort(f) - local count=band(flags,0x0FFF) - local offset=startoffset+readushort(f) - local deltas={} - local allpoints=(shape.nofpoints or 0) - local shared=false - local nofshared=0 - if band(flags,0x8000)~=0 then - local current=getposition(f) - setposition(f,offset) - shared,nofshared=readpoints(f) - offset=getposition(f) - setposition(f,current) - end - for j=1,count do - local size=readushort(f) - local flags=readushort(f) - local index=band(flags,0x0FFF) - local haspeak=band(flags,0x8000)~=0 - local intermediate=band(flags,0x4000)~=0 - local private=band(flags,0x2000)~=0 - local peak=nil - local start=nil - local stop=nil - local xvalues=nil - local yvalues=nil - local points=shared - local nofpoints=nofshared - if haspeak then - peak=readtuplerecord(f,nofaxis) - else - if index+1>#tuples then - report("error, bad tuple index",index) - end - peak=tuples[index+1] - end - if intermediate then - start=readtuplerecord(f,nofaxis) - stop=readtuplerecord(f,nofaxis) - end - if size>0 then - local current=getposition(f) - setposition(f,offset) - if private then - points,nofpoints=readpoints(f) - end - if nofpoints==0 then - nofpoints=allpoints+4 - end - if nofpoints>0 then - xvalues=readdeltas(f,nofpoints) - yvalues=readdeltas(f,nofpoints) - end - offset=offset+size - setposition(f,current) - end - if not xvalues and not yvalues then - points=nil - end - local s=1 - for i=1,nofaxis do - local f=factors[i] - local peak=peak and peak [i] or 0 - local start=start and start[i] or (peak<0 and peak or 0) - local stop=stop and stop [i] or (peak>0 and peak or 0) - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - if s==0 then - if name then - report("no deltas applied for glyph %a",name) - end - else - deltas[#deltas+1]={ - factor=s, - points=points, - xvalues=xvalues, - yvalues=yvalues, - } - end - end - if shape.type=="glyph" then - applyaxis(glyph,shape,deltas,dowidth) - else - shape.deltas=deltas - end - end - end - startoffset=nextoffset - end - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp” e1c275ded4770aa6cbe0b1afbdfd0dde] --- - -if not modules then modules={} end modules ['font-dsp']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber=next,type,tonumber -local band=bit32.band -local extract=bit32.extract -local bor=bit32.bor -local lshift=bit32.lshift -local rshift=bit32.rshift -local gsub=string.gsub -local lower=string.lower -local sub=string.sub -local strip=string.strip -local tohash=table.tohash -local concat=table.concat -local copy=table.copy -local reversed=table.reversed -local sort=table.sort -local insert=table.insert -local round=math.round -local settings_to_hash=utilities.parsers.settings_to_hash_colon_too -local setmetatableindex=table.setmetatableindex -local formatters=string.formatters -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local sequenced=table.sequenced -local report=logs.reporter("otf reader") -local readers=fonts.handlers.otf.readers -local streamreader=readers.streamreader -local setposition=streamreader.setposition -local getposition=streamreader.getposition -local readuinteger=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 -local readinteger=streamreader.readinteger1 -local readshort=streamreader.readinteger2 -local readstring=streamreader.readstring -local readtag=streamreader.readtag -local readbytes=streamreader.readbytes -local readfixed=streamreader.readfixed4 -local read2dot14=streamreader.read2dot14 -local skipshort=streamreader.skipshort -local skipbytes=streamreader.skip -local readbytetable=streamreader.readbytetable -local readbyte=streamreader.readbyte -local readcardinaltable=streamreader.readcardinaltable -local readintegertable=streamreader.readintegertable -local readfword=readshort -local short=2 -local ushort=2 -local ulong=4 -directives.register("fonts.streamreader",function() - streamreader=utilities.streams - setposition=streamreader.setposition - getposition=streamreader.getposition - readuinteger=streamreader.readcardinal1 - readushort=streamreader.readcardinal2 - readulong=streamreader.readcardinal4 - readinteger=streamreader.readinteger1 - readshort=streamreader.readinteger2 - readstring=streamreader.readstring - readtag=streamreader.readtag - readbytes=streamreader.readbytes - readfixed=streamreader.readfixed4 - read2dot14=streamreader.read2dot14 - skipshort=streamreader.skipshort - skipbytes=streamreader.skip - readbytetable=streamreader.readbytetable - readbyte=streamreader.readbyte - readcardinaltable=streamreader.readcardinaltable - readintegertable=streamreader.readintegertable - readfword=readshort -end) -local gsubhandlers={} -local gposhandlers={} -readers.gsubhandlers=gsubhandlers -readers.gposhandlers=gposhandlers -local helpers=readers.helpers -local gotodatatable=helpers.gotodatatable -local setvariabledata=helpers.setvariabledata -local lookupidoffset=-1 -local classes={ - "base", - "ligature", - "mark", - "component", -} -local gsubtypes={ - "single", - "multiple", - "alternate", - "ligature", - "context", - "chainedcontext", - "extension", - "reversechainedcontextsingle", -} -local gpostypes={ - "single", - "pair", - "cursive", - "marktobase", - "marktoligature", - "marktomark", - "context", - "chainedcontext", - "extension", -} -local chaindirections={ - context=0, - chainedcontext=1, - reversechainedcontextsingle=-1, -} -local function setmetrics(data,where,tag,d) - local w=data[where] - if w then - local v=w[tag] - if v then - w[tag]=v+d - end - end -end -local variabletags={ - hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, - hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, - hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, - hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, - hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, - vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, - vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, - vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, - xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, - cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, - sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, - sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, - sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, - sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, - spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, - spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, - spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, - spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, - strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, - stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, - unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, - undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, -} -local read_cardinal={ - streamreader.readcardinal1, - streamreader.readcardinal2, - streamreader.readcardinal3, - streamreader.readcardinal4, -} -local read_integer={ - streamreader.readinteger1, - streamreader.readinteger2, - streamreader.readinteger3, - streamreader.readinteger4, -} -local lookupnames={ - gsub={ - single="gsub_single", - multiple="gsub_multiple", - alternate="gsub_alternate", - ligature="gsub_ligature", - context="gsub_context", - chainedcontext="gsub_contextchain", - reversechainedcontextsingle="gsub_reversecontextchain", - }, - gpos={ - single="gpos_single", - pair="gpos_pair", - cursive="gpos_cursive", - marktobase="gpos_mark2base", - marktoligature="gpos_mark2ligature", - marktomark="gpos_mark2mark", - context="gpos_context", - chainedcontext="gpos_contextchain", - } -} -local lookupflags=setmetatableindex(function(t,k) - local v={ - band(k,0x0008)~=0 and true or false, - band(k,0x0004)~=0 and true or false, - band(k,0x0002)~=0 and true or false, - band(k,0x0001)~=0 and true or false, - } - t[k]=v - return v -end) -local function axistofactors(str) - local t=settings_to_hash(str) - for k,v in next,t do - t[k]=tonumber(v) or v - end - return t -end -local hash=table.setmetatableindex(function(t,k) - local v=sequenced(axistofactors(k),",") - t[k]=v - return v -end) -helpers.normalizedaxishash=hash -local cleanname=fonts.names and fonts.names.cleanname or function(name) - return name and (gsub(lower(name),"[^%a%d]","")) or nil -end -helpers.cleanname=cleanname -function helpers.normalizedaxis(str) - return hash[str] or str -end -local function getaxisscale(segments,minimum,default,maximum,user) - if not minimum or not default or not maximum then - return false - end - if usermaximum then - user=maximum - end - if userdefault then - default=(user-default)/(maximum-default) - else - default=0 - end - if not segments then - return default - end - local e - for i=1,#segments do - local s=segments[i] - if type(s)~="number" then - report("using default axis scale") - return default - elseif s[1]>=default then - if s[2]==default then - return default - else - e=i - break - end - end - end - if e then - local b=segments[e-1] - local e=segments[e] - return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) - else - return false - end -end -local function getfactors(data,instancespec) - if instancespec==true then - elseif type(instancespec)~="string" or instancespec=="" then - return - end - local variabledata=data.variabledata - if not variabledata then - return - end - local instances=variabledata.instances - local axis=variabledata.axis - local segments=variabledata.segments - if instances and axis then - local values - if instancespec==true then - values={} - for i=1,#axis do - values[i]={ - value=axis[i].default, - } - end - else - for i=1,#instances do - local instance=instances[i] - if cleanname(instance.subfamily)==instancespec then - values=instance.values - break - end - end - end - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) - end - return factors - end - local values=axistofactors(hash[instancespec] or instancespec) - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - local d=a.default - factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) - end - return factors - end - end -end -local function getscales(regions,factors) - local scales={} - for i=1,#regions do - local region=regions[i] - local s=1 - for j=1,#region do - local axis=region[j] - local f=factors[j] - local start=axis.start - local peak=axis.peak - local stop=axis.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - scales[i]=s - end - return scales -end -helpers.getaxisscale=getaxisscale -helpers.getfactors=getfactors -helpers.getscales=getscales -helpers.axistofactors=axistofactors -local function readvariationdata(f,storeoffset,factors) - local position=getposition(f) - setposition(f,storeoffset) - local format=readushort(f) - local regionoffset=storeoffset+readulong(f) - local nofdeltadata=readushort(f) - local deltadata=readcardinaltable(f,nofdeltadata,ulong) - setposition(f,regionoffset) - local nofaxis=readushort(f) - local nofregions=readushort(f) - local regions={} - for i=1,nofregions do - local t={} - for i=1,nofaxis do - t[i]={ - start=read2dot14(f), - peak=read2dot14(f), - stop=read2dot14(f), - } - end - regions[i]=t - end - if factors then - for i=1,nofdeltadata do - setposition(f,storeoffset+deltadata[i]) - local nofdeltasets=readushort(f) - local nofshorts=readushort(f) - local nofregions=readushort(f) - local usedregions={} - local deltas={} - for i=1,nofregions do - usedregions[i]=regions[readushort(f)+1] - end - for i=1,nofdeltasets do - local t=readintegertable(f,nofshorts,short) - for i=nofshorts+1,nofregions do - t[i]=readinteger(f) - end - deltas[i]=t - end - deltadata[i]={ - regions=usedregions, - deltas=deltas, - scales=factors and getscales(usedregions,factors) or nil, - } - end - end - setposition(f,position) - return regions,deltadata -end -helpers.readvariationdata=readvariationdata -local function readcoverage(f,offset,simple) - setposition(f,offset) - local coverageformat=readushort(f) - if coverageformat==1 then - local nofcoverage=readushort(f) - if simple then - if nofcoverage==1 then - return { readushort(f) } - elseif nofcoverage==2 then - return { readushort(f),readushort(f) } - else - return readcardinaltable(f,nofcoverage,ushort) - end - elseif nofcoverage==1 then - return { [readushort(f)]=0 } - elseif nofcoverage==2 then - return { [readushort(f)]=0,[readushort(f)]=1 } - else - local coverage={} - for i=0,nofcoverage-1 do - coverage[readushort(f)]=i - end - return coverage - end - elseif coverageformat==2 then - local nofranges=readushort(f) - local coverage={} - local n=simple and 1 or 0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local coverindex=readushort(f) - if simple then - for i=firstindex,lastindex do - coverage[n]=i - n=n+1 - end - else - for i=firstindex,lastindex do - coverage[i]=n - n=n+1 - end - end - end - return coverage - else - report("unknown coverage format %a ",coverageformat) - return {} - end -end -local function readclassdef(f,offset,preset) - setposition(f,offset) - local classdefformat=readushort(f) - local classdef={} - if type(preset)=="number" then - for k=0,preset-1 do - classdef[k]=1 - end - end - if classdefformat==1 then - local index=readushort(f) - local nofclassdef=readushort(f) - for i=1,nofclassdef do - classdef[index]=readushort(f)+1 - index=index+1 - end - elseif classdefformat==2 then - local nofranges=readushort(f) - local n=0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=readushort(f)+1 - for i=firstindex,lastindex do - classdef[i]=class - end - end - else - report("unknown classdef format %a ",classdefformat) - end - if type(preset)=="table" then - for k in next,preset do - if not classdef[k] then - classdef[k]=1 - end - end - end - return classdef -end -local function classtocoverage(defs) - if defs then - local list={} - for index,class in next,defs do - local c=list[class] - if c then - c[#c+1]=index - else - list[class]={ index } - end - end - return list - end -end -local skips={ [0]=0, - 1, - 1, - 2, - 1, - 2, - 2, - 3, - 2, - 2, - 3, - 2, - 3, - 3, - 4, -} -local function readvariation(f,offset) - local p=getposition(f) - setposition(f,offset) - local outer=readushort(f) - local inner=readushort(f) - local format=readushort(f) - setposition(f,p) - if format==0x8000 then - return outer,inner - end -end -local function readposition(f,format,mainoffset,getdelta) - if format==0 then - return false - end - if format==0x04 then - local h=readshort(f) - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - if format==0x05 then - local x=readshort(f) - local h=readshort(f) - if x==0 and h==0 then - return true - else - return { x,0,h,0 } - end - end - if format==0x44 then - local h=readshort(f) - if getdelta then - local d=readshort(f) - if d>0 then - local outer,inner=readvariation(f,mainoffset+d) - if outer then - h=h+getdelta(outer,inner) - end - end - else - skipshort(f,1) - end - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - local x=band(format,0x1)~=0 and readshort(f) or 0 - local y=band(format,0x2)~=0 and readshort(f) or 0 - local h=band(format,0x4)~=0 and readshort(f) or 0 - local v=band(format,0x8)~=0 and readshort(f) or 0 - if format>=0x10 then - local X=band(format,0x10)~=0 and skipshort(f) or 0 - local Y=band(format,0x20)~=0 and skipshort(f) or 0 - local H=band(format,0x40)~=0 and skipshort(f) or 0 - local V=band(format,0x80)~=0 and skipshort(f) or 0 - local s=skips[extract(format,4,4)] - if s>0 then - skipshort(f,s) - end - if getdelta then - if X>0 then - local outer,inner=readvariation(f,mainoffset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,mainoffset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - if H>0 then - local outer,inner=readvariation(f,mainoffset+H) - if outer then - h=h+getdelta(outer,inner) - end - end - if V>0 then - local outer,inner=readvariation(f,mainoffset+V) - if outer then - v=v+getdelta(outer,inner) - end - end - end - return { x,y,h,v } - elseif x==0 and y==0 and h==0 and v==0 then - return true - else - return { x,y,h,v } - end -end -local function readanchor(f,offset,getdelta) - if not offset or offset==0 then - return nil - end - setposition(f,offset) - local format=readshort(f) - local x=readshort(f) - local y=readshort(f) - if format==3 then - if getdelta then - local X=readshort(f) - local Y=readshort(f) - if X>0 then - local outer,inner=readvariation(f,offset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,offset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - else - skipshort(f,2) - end - return { x,y } - else - return { x,y } - end -end -local function readfirst(f,offset) - if offset then - setposition(f,offset) - end - return { readushort(f) } -end -function readarray(f,offset) - if offset then - setposition(f,offset) - end - local n=readushort(f) - if n==1 then - return { readushort(f) },1 - elseif n>0 then - return readcardinaltable(f,n,ushort),n - end -end -local function readcoveragearray(f,offset,t,simple) - if not t then - return nil - end - local n=#t - if n==0 then - return nil - end - for i=1,n do - t[i]=readcoverage(f,offset+t[i],simple) - end - return t -end -local function covered(subset,all) - local used,u - for i=1,#subset do - local s=subset[i] - if all[s] then - if used then - u=u+1 - used[u]=s - else - u=1 - used={ s } - end - end - end - return used -end -local function readlookuparray(f,noflookups,nofcurrent) - local lookups={} - if noflookups>0 then - local length=0 - for i=1,noflookups do - local index=readushort(f)+1 - if index>length then - length=index - end - local lookup=readushort(f)+1 - local list=lookups[index] - if list then - list[#list+1]=lookup - else - lookups[index]={ lookup } - end - end - for index=1,length do - if not lookups[index] then - lookups[index]=false - end - end - end - return lookups -end -local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - end - end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) - end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local currentclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage) - currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - else - report("no coverage") - end - else - report("no coverage class") - end - end - end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) - end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local nofglyphs=readushort(f) - local noflookups=readushort(f) - local current=readcardinaltable(f,nofglyphs,ushort) - local lookups=readlookuparray(f,noflookups,#current) - current=readcoveragearray(f,tableoffset,current,true) - return { - format="coverage", - rules={ - { - current=current, - lookups=lookups, - } - } - } - else - report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) - end -end -local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]={ readushort(f) } - end - end - local nofcurrent=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]={ readushort(f) } - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - end - end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) - end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local beforeclassdef=readushort(f) - local currentclassdef=readushort(f) - local afterclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - local coverage=readcoverage(f,tableoffset+coverage) - local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) - local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) - local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]=beforeclasses[readushort(f)+1] - end - end - local nofcurrent=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]=afterclasses[readushort(f)+1] - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - else - report("no coverage") - end - else - report("class is not covered") - end - end - end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) - end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local before=readarray(f) - local current=readarray(f) - local after=readarray(f) - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,#current) - before=readcoveragearray(f,tableoffset,before,true) - current=readcoveragearray(f,tableoffset,current,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="coverage", - rules={ - { - before=before, - current=current, - after=after, - lookups=lookups, - } - } - } - else - report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) - end -end -local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local lookuptype=types[readushort(f)] - local faroffset=readulong(f) - local handler=handlers[lookuptype] - if handler then - return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype - else - report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") - end - else - report("unsupported subtype %a in %s %s",subtype,what,"extension") - end -end -function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local delta=readshort(f) - local coverage=readcoverage(f,tableoffset+coverage) - for index in next,coverage do - local newindex=(index+delta)%65536 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=newindex - end - end - return { - coverage=coverage - } - elseif subtype==2 then - local coverage=readushort(f) - local nofreplacements=readushort(f) - local replacements=readcardinaltable(f,nofreplacements,ushort) - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=replacements[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"single") - end -end -local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsequence=readushort(f) - local sequences=readcardinaltable(f,nofsequence,ushort) - for i=1,nofsequence do - setposition(f,tableoffset+sequences[i]) - sequences[i]=readcardinaltable(f,readushort(f),ushort) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=sequences[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,what) - end -end -function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") -end -function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") -end -function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsets=readushort(f) - local ligatures=readcardinaltable(f,nofsets,ushort) - for i=1,nofsets do - local offset=lookupoffset+offset+ligatures[i] - setposition(f,offset) - local n=readushort(f) - if n==1 then - ligatures[i]={ offset+readushort(f) } - else - local l={} - for i=1,n do - l[i]=offset+readushort(f) - end - ligatures[i]=l - end - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - local hash={} - local ligatures=ligatures[newindex+1] - for i=1,#ligatures do - local offset=ligatures[i] - setposition(f,offset) - local lig=readushort(f) - local cnt=readushort(f) - local hsh=hash - for i=2,cnt do - local c=readushort(f) - local h=hsh[c] - if not h then - h={} - hsh[c]=h - end - hsh=h - end - hsh.ligature=lig - end - coverage[index]=hash - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"ligature") - end -end -function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" -end -function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" -end -function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") -end -function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local current=readfirst(f) - local before=readarray(f) - local after=readarray(f) - local replacements=readarray(f) - current=readcoveragearray(f,tableoffset,current,true) - before=readcoveragearray(f,tableoffset,before,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="reversecoverage", - rules={ - { - before=before, - current=current, - after=after, - replacements=replacements, - } - } - },"reversechainedcontextsingle" - else - report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") - end -end -local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - local done={} - for i=1,#sets do - local offset=sets[i] - local reused=done[offset] - if not reused then - offset=tableoffset+offset - setposition(f,offset) - local n=readushort(f) - reused={} - for i=1,n do - reused[i]={ - readushort(f), - readposition(f,format1,offset,getdelta), - readposition(f,format2,offset,getdelta), - } - end - done[offset]=reused - end - sets[i]=reused - end - return sets -end -local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) - local classlist1={} - for i=1,nofclasses1 do - local classlist2={} - classlist1[i]=classlist2 - for j=1,nofclasses2 do - local one=readposition(f,format1,mainoffset,getdelta) - local two=readposition(f,format2,mainoffset,getdelta) - if one or two then - classlist2[j]={ one,two } - else - classlist2[j]=false - end - end - end - return classlist1 -end -function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format=readushort(f) - local value=readposition(f,format,tableoffset,getdelta) - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=value - end - return { - format="single", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format=readushort(f) - local nofvalues=readushort(f) - local values={} - for i=1,nofvalues do - values[i]=readposition(f,format,tableoffset,getdelta) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=values[newindex+1] - end - return { - format="single", - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"single") - end -end -function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local sets=readarray(f) - sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - local shared={} - for index,newindex in next,coverage do - local set=sets[newindex+1] - local hash={} - for i=1,#set do - local value=set[i] - if value then - local other=value[1] - local share=shared[value] - if share==nil then - local first=value[2] - local second=value[3] - if first or second then - share={ first,second or nil } - else - share=false - end - shared[value]=share - end - hash[other]=share or nil - end - end - coverage[index]=hash - end - return { - shared=shared and true or nil, - format="pair", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local classdef1=readushort(f) - local classdef2=readushort(f) - local nofclasses1=readushort(f) - local nofclasses2=readushort(f) - local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - classdef1=readclassdef(f,tableoffset+classdef1,coverage) - classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) - local usedcoverage={} - local shared={} - for g1,c1 in next,classdef1 do - if coverage[g1] then - local l1=classlist[c1] - if l1 then - local hash={} - for paired,class in next,classdef2 do - local offsets=l1[class] - if offsets then - local first=offsets[1] - local second=offsets[2] - if first or second then - local s1=shared[first] - if s1==nil then - s1={} - shared[first]=s1 - end - local s2=s1[second] - if s2==nil then - s2={ first,second or nil } - s1[second]=s2 - end - hash[paired]=s2 - end - end - end - usedcoverage[g1]=hash - end - end - end - return { - shared=shared and true or nil, - format="pair", - coverage=usedcoverage, - } - elseif subtype==3 then - report("yet unsupported subtype %a in %a positioning",subtype,"pair") - else - report("unsupported subtype %a in %a positioning",subtype,"pair") - end -end -function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=tableoffset+readushort(f) - local nofrecords=readushort(f) - local records={} - for i=1,nofrecords do - local entry=readushort(f) - local exit=readushort(f) - records[i]={ - entry~=0 and (tableoffset+entry) or false, - exit~=0 and (tableoffset+exit ) or nil, - } - end - local cc=(fontdata.temporary.cursivecount or 0)+1 - fontdata.temporary.cursivecount=cc - cc="cc-"..cc - coverage=readcoverage(f,coverage) - for i=1,nofrecords do - local r=records[i] - records[i]={ - cc, - readanchor(f,r[1],getdelta) or false, - readanchor(f,r[2],getdelta) or nil, - } - end - for index,newindex in next,coverage do - coverage[index]=records[newindex+1] - end - return { - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"cursive") - end -end -local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local markcoverage=tableoffset+readushort(f) - local basecoverage=tableoffset+readushort(f) - local nofclasses=readushort(f) - local markoffset=tableoffset+readushort(f) - local baseoffset=tableoffset+readushort(f) - local markcoverage=readcoverage(f,markcoverage) - local basecoverage=readcoverage(f,basecoverage,true) - setposition(f,markoffset) - local markclasses={} - local nofmarkclasses=readushort(f) - local lastanchor=fontdata.lastanchor or 0 - local usedanchors={} - for i=1,nofmarkclasses do - local class=readushort(f)+1 - local offset=readushort(f) - if offset==0 then - markclasses[i]=false - else - markclasses[i]={ class,markoffset+offset } - end - usedanchors[class]=true - end - for i=1,nofmarkclasses do - local mc=markclasses[i] - if mc then - mc[2]=readanchor(f,mc[2],getdelta) - end - end - setposition(f,baseoffset) - local nofbaserecords=readushort(f) - local baserecords={} - if ligature then - for i=1,nofbaserecords do - local offset=readushort(f) - if offset==0 then - baserecords[i]=false - else - baserecords[i]=baseoffset+offset - end - end - for i=1,nofbaserecords do - local recordoffset=baserecords[i] - if recordoffset then - setposition(f,recordoffset) - local nofcomponents=readushort(f) - local components={} - for i=1,nofcomponents do - local classes={} - for i=1,nofclasses do - local offset=readushort(f) - if offset~=0 then - classes[i]=recordoffset+offset - else - classes[i]=false - end - end - components[i]=classes - end - baserecords[i]=components - end - end - local baseclasses={} - for i=1,nofclasses do - baseclasses[i]={} - end - for i=1,nofbaserecords do - local components=baserecords[i] - if components then - local b=basecoverage[i] - for c=1,#components do - local classes=components[c] - if classes then - for i=1,nofclasses do - local anchor=readanchor(f,classes[i],getdelta) - local bclass=baseclasses[i] - local bentry=bclass[b] - if bentry then - bentry[c]=anchor - else - bclass[b]={ [c]=anchor } - end - end - end - end - end - end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="ligature", - baseclasses=baseclasses, - coverage=markcoverage, - } - else - for i=1,nofbaserecords do - local r={} - for j=1,nofclasses do - local offset=readushort(f) - if offset==0 then - r[j]=false - else - r[j]=baseoffset+offset - end - end - baserecords[i]=r - end - local baseclasses={} - for i=1,nofclasses do - baseclasses[i]={} - end - for i=1,nofbaserecords do - local r=baserecords[i] - local b=basecoverage[i] - for j=1,nofclasses do - baseclasses[j][b]=readanchor(f,r[j],getdelta) - end - end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="base", - baseclasses=baseclasses, - coverage=markcoverage, - } - end - else - report("unsupported subtype %a in",subtype) - end -end -function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) -end -function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) -end -function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) -end -function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" -end -function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" -end -function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") -end -do - local plugins={} - function plugins.size(f,fontdata,tableoffset,feature) - if fontdata.designsize then - else - local function check(offset) - setposition(f,offset) - local designsize=readushort(f) - if designsize>0 then - local fontstyleid=readushort(f) - local guimenuid=readushort(f) - local minsize=readushort(f) - local maxsize=readushort(f) - if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then - minsize=designsize - maxsize=designsize - end - if designsize>=minsize and designsize<=maxsize then - return minsize,maxsize,designsize - end - end - end - local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) - if not designsize then - minsize,maxsize,designsize=check(tableoffset+feature.parameters) - if designsize then - report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") - else - report("bad size feature in %a,",fontdata.filename or "?") - end - end - if designsize then - fontdata.minsize=minsize - fontdata.maxsize=maxsize - fontdata.designsize=designsize - end - end - end - local function reorderfeatures(fontdata,scripts,features) - local scriptlangs={} - local featurehash={} - local featureorder={} - for script,languages in next,scripts do - for language,record in next,languages do - local hash={} - local list=record.featureindices - for k=1,#list do - local index=list[k] - local feature=features[index] - local lookups=feature.lookups - local tag=feature.tag - if tag then - hash[tag]=true - end - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local o=featureorder[lookup] - if o then - local okay=true - for i=1,#o do - if o[i]==tag then - okay=false - break - end - end - if okay then - o[#o+1]=tag - end - else - featureorder[lookup]={ tag } - end - local f=featurehash[lookup] - if f then - local h=f[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - f[tag]={ [script]={ [language]=true } } - end - else - featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } - end - local h=scriptlangs[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - scriptlangs[tag]={ [script]={ [language]=true } } - end - end - end - end - end - end - return scriptlangs,featurehash,featureorder - end - local function readscriplan(f,fontdata,scriptoffset) - setposition(f,scriptoffset) - local nofscripts=readushort(f) - local scripts={} - for i=1,nofscripts do - scripts[readtag(f)]=scriptoffset+readushort(f) - end - local languagesystems=setmetatableindex("table") - for script,offset in next,scripts do - setposition(f,offset) - local defaultoffset=readushort(f) - local noflanguages=readushort(f) - local languages={} - if defaultoffset>0 then - languages.dflt=languagesystems[offset+defaultoffset] - end - for i=1,noflanguages do - local language=readtag(f) - local offset=offset+readushort(f) - languages[language]=languagesystems[offset] - end - scripts[script]=languages - end - for offset,usedfeatures in next,languagesystems do - if offset>0 then - setposition(f,offset) - local featureindices={} - usedfeatures.featureindices=featureindices - usedfeatures.lookuporder=readushort(f) - usedfeatures.requiredindex=readushort(f) - local noffeatures=readushort(f) - for i=1,noffeatures do - featureindices[i]=readushort(f)+1 - end - end - end - return scripts - end - local function readfeatures(f,fontdata,featureoffset) - setposition(f,featureoffset) - local features={} - local noffeatures=readushort(f) - for i=1,noffeatures do - features[i]={ - tag=readtag(f), - offset=readushort(f) - } - end - for i=1,noffeatures do - local feature=features[i] - local offset=featureoffset+feature.offset - setposition(f,offset) - local parameters=readushort(f) - local noflookups=readushort(f) - if noflookups>0 then - local lookups=readcardinaltable(f,noflookups,ushort) - feature.lookups=lookups - for j=1,noflookups do - lookups[j]=lookups[j]+1 - end - end - if parameters>0 then - feature.parameters=parameters - local plugin=plugins[feature.tag] - if plugin then - plugin(f,fontdata,featureoffset,feature) - end - end - end - return features - end - local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - setposition(f,lookupoffset) - local noflookups=readushort(f) - local lookups=readcardinaltable(f,noflookups,ushort) - for lookupid=1,noflookups do - local offset=lookups[lookupid] - setposition(f,lookupoffset+offset) - local subtables={} - local typebits=readushort(f) - local flagbits=readushort(f) - local lookuptype=lookuptypes[typebits] - local lookupflags=lookupflags[flagbits] - local nofsubtables=readushort(f) - for j=1,nofsubtables do - subtables[j]=offset+readushort(f) - end - local markclass=band(flagbits,0x0010)~=0 - if markclass then - markclass=readushort(f) - end - local markset=rshift(flagbits,8) - if markset>0 then - markclass=markset - end - lookups[lookupid]={ - type=lookuptype, - flags=lookupflags, - name=lookupid, - subtables=subtables, - markclass=markclass, - features=featurehash[lookupid], - order=featureorder[lookupid], - } - end - return lookups - end - local f_lookupname=formatters["%s_%s_%s"] - local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - local sequences=fontdata.sequences or {} - local sublookuplist=fontdata.sublookups or {} - fontdata.sequences=sequences - fontdata.sublookups=sublookuplist - local nofsublookups=#sublookuplist - local nofsequences=#sequences - local lastsublookup=nofsublookups - local lastsequence=nofsequences - local lookupnames=lookupnames[what] - local sublookuphash={} - local sublookupcheck={} - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs or #glyphs - local noflookups=#lookups - local lookupprefix=sub(what,2,2) - local usedlookups=false - for lookupid=1,noflookups do - local lookup=lookups[lookupid] - local lookuptype=lookup.type - local subtables=lookup.subtables - local features=lookup.features - local handler=lookuphandlers[lookuptype] - if handler then - local nofsubtables=#subtables - local order=lookup.order - local flags=lookup.flags - if flags[1] then flags[1]="mark" end - if flags[2] then flags[2]="ligature" end - if flags[3] then flags[3]="base" end - local markclass=lookup.markclass - if nofsubtables>0 then - local steps={} - local nofsteps=0 - local oldtype=nil - for s=1,nofsubtables do - local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) - if lt then - lookuptype=lt - if oldtype and lt~=oldtype then - report("messy %s lookup type %a and %a",what,lookuptype,oldtype) - end - oldtype=lookuptype - end - if not step then - report("unsupported %s lookup type %a",what,lookuptype) - else - nofsteps=nofsteps+1 - steps[nofsteps]=step - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - local current=rule.current - local after=rule.after - local replacements=rule.replacements - if before then - for i=1,#before do - before[i]=tohash(before[i]) - end - rule.before=reversed(before) - end - if current then - if replacements then - local first=current[1] - local hash={} - local repl={} - for i=1,#first do - local c=first[i] - hash[c]=true - repl[c]=replacements[i] - end - rule.current={ hash } - rule.replacements=repl - else - for i=1,#current do - current[i]=tohash(current[i]) - end - end - else - end - if after then - for i=1,#after do - after[i]=tohash(after[i]) - end - end - if usedlookups then - local lookups=rule.lookups - if lookups then - for k,v in next,lookups do - if v then - for k,v in next,v do - usedlookups[v]=usedlookups[v]+1 - end - end - end - end - end - end - end - end - end - if nofsteps~=nofsubtables then - report("bogus subtables removed in %s lookup type %a",what,lookuptype) - end - lookuptype=lookupnames[lookuptype] or lookuptype - if features then - nofsequences=nofsequences+1 - local l={ - index=nofsequences, - name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - order=order, - features=features, - } - sequences[nofsequences]=l - lookup.done=l - else - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - } - sublookuplist[nofsublookups]=l - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=0 - lookup.done=l - end - else - report("no subtables for lookup %a",lookupid) - end - else - report("no handler for lookup %a with type %a",lookupid,lookuptype) - end - end - if usedlookups then - report("used %s lookups: % t",what,sortedkeys(usedlookups)) - end - local reported={} - local function report_issue(i,what,sequence,kind) - local name=sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) - reported[name]=true - end - end - for i=lastsequence+1,nofsequences do - local sequence=sequences[i] - local steps=sequence.steps - for i=1,#steps do - local step=steps[i] - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local rlookups=rule.lookups - if not rlookups then - report_issue(i,what,sequence,"no") - elseif not next(rlookups) then - rule.lookups=nil - else - local length=#rlookups - for index=1,length do - local lookuplist=rlookups[index] - if lookuplist then - local length=#lookuplist - local found={} - local noffound=0 - for index=1,length do - local lookupid=lookuplist[index] - if lookupid then - local h=sublookuphash[lookupid] - if not h then - local lookup=lookups[lookupid] - if lookup then - local d=lookup.done - if d then - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), - derived=true, - steps=d.steps, - nofsteps=d.nofsteps, - type=d.lookuptype or "gsub_single", - markclass=d.markclass or nil, - flags=d.flags, - } - sublookuplist[nofsublookups]=copy(l) - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=1 - h=nofsublookups - else - report_issue(i,what,sequence,"missing") - rule.lookups=nil - break - end - else - report_issue(i,what,sequence,"bad") - rule.lookups=nil - break - end - else - sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 - end - if h then - noffound=noffound+1 - found[noffound]=h - end - end - end - rlookups[index]=noffound>0 and found or false - else - rlookups[index]=false - end - end - end - end - end - end - end - for i,n in sortedhash(sublookupcheck) do - local l=lookups[i] - local t=l.type - if n==0 and t~="extension" then - local d=l.done - report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) - end - end - end - local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) - setposition(f,variationsoffset) - local version=readulong(f) - local nofrecords=readulong(f) - local records={} - for i=1,nofrecords do - records[i]={ - conditions=readulong(f), - substitutions=readulong(f), - } - end - for i=1,nofrecords do - local record=records[i] - local offset=record.conditions - if offset==0 then - record.condition=nil - record.matchtype="always" - else - local offset=variationsoffset+offset - setposition(f,offset) - local nofconditions=readushort(f) - local conditions={} - for i=1,nofconditions do - conditions[i]=offset+readulong(f) - end - record.conditions=conditions - record.matchtype="condition" - end - end - for i=1,nofrecords do - local record=records[i] - if record.matchtype=="condition" then - local conditions=record.conditions - for i=1,#conditions do - setposition(f,conditions[i]) - conditions[i]={ - format=readushort(f), - axis=readushort(f), - minvalue=read2dot14(f), - maxvalue=read2dot14(f), - } - end - end - end - for i=1,nofrecords do - local record=records[i] - local offset=record.substitutions - if offset==0 then - record.substitutions={} - else - setposition(f,variationsoffset+offset) - local version=readulong(f) - local nofsubstitutions=readushort(f) - local substitutions={} - for i=1,nofsubstitutions do - substitutions[readushort(f)]=readulong(f) - end - for index,alternates in sortedhash(substitutions) do - if index==0 then - record.substitutions=false - else - local tableoffset=variationsoffset+offset+alternates - setposition(f,tableoffset) - local parameters=readulong(f) - local noflookups=readushort(f) - local lookups=readcardinaltable(f,noflookups,ushort) - record.substitutions=lookups - end - end - end - end - setvariabledata(fontdata,"features",records) - end - local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) - local tableoffset=gotodatatable(f,fontdata,what,true) - if tableoffset then - local version=readulong(f) - local scriptoffset=tableoffset+readushort(f) - local featureoffset=tableoffset+readushort(f) - local lookupoffset=tableoffset+readushort(f) - local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 - if not scriptoffset then - return - end - local scripts=readscriplan(f,fontdata,scriptoffset) - local features=readfeatures(f,fontdata,featureoffset) - local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) - if fontdata.features then - fontdata.features[what]=scriptlangs - else - fontdata.features={ [what]=scriptlangs } - end - if not lookupstoo then - return - end - local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - if lookups then - resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - end - if variationsoffset>0 then - loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) - end - end - end - local function checkkerns(f,fontdata,specification) - local datatable=fontdata.tables.kern - if not datatable then - return - end - local features=fontdata.features - local gposfeatures=features and features.gpos - local name - if not gposfeatures or not gposfeatures.kern then - name="kern" - elseif specification.globalkerns then - name="globalkern" - else - report("ignoring global kern table, using gpos kern feature") - return - end - setposition(f,datatable.offset) - local version=readushort(f) - local noftables=readushort(f) - if noftables>1 then - report("adding global kern table as gpos feature %a",name) - local kerns=setmetatableindex("table") - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)]=readfword(f) - end - elseif format==2 then - else - end - end - local feature={ dflt={ dflt=true } } - if not features then - fontdata.features={ gpos={ [name]=feature } } - elseif not gposfeatures then - fontdata.features.gpos={ [name]=feature } - else - gposfeatures[name]=feature - end - local sequences=fontdata.sequences - if not sequences then - sequences={} - fontdata.sequences=sequences - end - local nofsequences=#sequences+1 - sequences[nofsequences]={ - index=nofsequences, - name=name, - steps={ - { - coverage=kerns, - format="kern", - }, - }, - nofsteps=1, - type="gpos_pair", - flags={ false,false,false,false }, - order={ name }, - features={ [name]=feature }, - } - else - report("ignoring empty kern table of feature %a",name) - end - end - function readers.gsub(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) - end - end - function readers.gpos(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) - if specification.lookups then - checkkerns(f,fontdata,specification) - end - end - end -end -function readers.gdef(f,fontdata,specification) - if not specification.glyphs then - return - end - local datatable=fontdata.tables.gdef - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readulong(f) - local classoffset=readushort(f) - local attachmentoffset=readushort(f) - local ligaturecarets=readushort(f) - local markclassoffset=readushort(f) - local marksetsoffset=version>=0x00010002 and readushort(f) or 0 - local varsetsoffset=version>=0x00010003 and readulong(f) or 0 - local glyphs=fontdata.glyphs - local marks={} - local markclasses=setmetatableindex("table") - local marksets=setmetatableindex("table") - fontdata.marks=marks - fontdata.markclasses=markclasses - fontdata.marksets=marksets - if classoffset~=0 then - setposition(f,tableoffset+classoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - local class=classes[readushort(f)] - if class=="mark" then - marks[index]=true - end - glyphs[index].class=class - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class=class - if class=="mark" then - marks[index]=true - end - end - end - end - end - end - if markclassoffset~=0 then - setposition(f,tableoffset+markclassoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - markclasses[readushort(f)][index]=true - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=markclasses[readushort(f)] - for index=firstindex,lastindex do - class[index]=true - end - end - end - end - if marksetsoffset~=0 then - marksetsoffset=tableoffset+marksetsoffset - setposition(f,marksetsoffset) - local format=readushort(f) - if format==1 then - local nofsets=readushort(f) - local sets=readcardinaltable(f,nofsets,ulong) - for i=1,nofsets do - local offset=sets[i] - if offset~=0 then - marksets[i]=readcoverage(f,marksetsoffset+offset) - end - end - end - end - local factors=specification.factors - if (specification.variable or factors) and varsetsoffset~=0 then - local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) - if factors then - fontdata.temporary.getdelta=function(outer,inner) - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local dd=0 - for i=1,#scales do - local di=d[i] - if di then - dd=dd+scales[i]*di - else - break - end - end - return round(dd) - end - end - return 0 - end - end - end - end -end -local function readmathvalue(f) - local v=readshort(f) - skipshort(f,1) - return v -end -local function readmathconstants(f,fontdata,offset) - setposition(f,offset) - fontdata.mathconstants={ - ScriptPercentScaleDown=readshort(f), - ScriptScriptPercentScaleDown=readshort(f), - DelimitedSubFormulaMinHeight=readushort(f), - DisplayOperatorMinHeight=readushort(f), - MathLeading=readmathvalue(f), - AxisHeight=readmathvalue(f), - AccentBaseHeight=readmathvalue(f), - FlattenedAccentBaseHeight=readmathvalue(f), - SubscriptShiftDown=readmathvalue(f), - SubscriptTopMax=readmathvalue(f), - SubscriptBaselineDropMin=readmathvalue(f), - SuperscriptShiftUp=readmathvalue(f), - SuperscriptShiftUpCramped=readmathvalue(f), - SuperscriptBottomMin=readmathvalue(f), - SuperscriptBaselineDropMax=readmathvalue(f), - SubSuperscriptGapMin=readmathvalue(f), - SuperscriptBottomMaxWithSubscript=readmathvalue(f), - SpaceAfterScript=readmathvalue(f), - UpperLimitGapMin=readmathvalue(f), - UpperLimitBaselineRiseMin=readmathvalue(f), - LowerLimitGapMin=readmathvalue(f), - LowerLimitBaselineDropMin=readmathvalue(f), - StackTopShiftUp=readmathvalue(f), - StackTopDisplayStyleShiftUp=readmathvalue(f), - StackBottomShiftDown=readmathvalue(f), - StackBottomDisplayStyleShiftDown=readmathvalue(f), - StackGapMin=readmathvalue(f), - StackDisplayStyleGapMin=readmathvalue(f), - StretchStackTopShiftUp=readmathvalue(f), - StretchStackBottomShiftDown=readmathvalue(f), - StretchStackGapAboveMin=readmathvalue(f), - StretchStackGapBelowMin=readmathvalue(f), - FractionNumeratorShiftUp=readmathvalue(f), - FractionNumeratorDisplayStyleShiftUp=readmathvalue(f), - FractionDenominatorShiftDown=readmathvalue(f), - FractionDenominatorDisplayStyleShiftDown=readmathvalue(f), - FractionNumeratorGapMin=readmathvalue(f), - FractionNumeratorDisplayStyleGapMin=readmathvalue(f), - FractionRuleThickness=readmathvalue(f), - FractionDenominatorGapMin=readmathvalue(f), - FractionDenominatorDisplayStyleGapMin=readmathvalue(f), - SkewedFractionHorizontalGap=readmathvalue(f), - SkewedFractionVerticalGap=readmathvalue(f), - OverbarVerticalGap=readmathvalue(f), - OverbarRuleThickness=readmathvalue(f), - OverbarExtraAscender=readmathvalue(f), - UnderbarVerticalGap=readmathvalue(f), - UnderbarRuleThickness=readmathvalue(f), - UnderbarExtraDescender=readmathvalue(f), - RadicalVerticalGap=readmathvalue(f), - RadicalDisplayStyleVerticalGap=readmathvalue(f), - RadicalRuleThickness=readmathvalue(f), - RadicalExtraAscender=readmathvalue(f), - RadicalKernBeforeDegree=readmathvalue(f), - RadicalKernAfterDegree=readmathvalue(f), - RadicalDegreeBottomRaisePercent=readshort(f), - } -end -local function readmathglyphinfo(f,fontdata,offset) - setposition(f,offset) - local italics=readushort(f) - local accents=readushort(f) - local extensions=readushort(f) - local kerns=readushort(f) - local glyphs=fontdata.glyphs - if italics~=0 then - setposition(f,offset+italics) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+italics+coverage,true) - setposition(f,offset+italics+4) - for i=1,nofglyphs do - local italic=readmathvalue(f) - if italic~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ italic=italic } - else - math.italic=italic - end - end - end - fontdata.hasitalics=true - end - if accents~=0 then - setposition(f,offset+accents) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+accents+coverage,true) - setposition(f,offset+accents+4) - for i=1,nofglyphs do - local accent=readmathvalue(f) - if accent~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ accent=accent } - else - math.accent=accent - end - end - end - end - if extensions~=0 then - setposition(f,offset+extensions) - end - if kerns~=0 then - local kernoffset=offset+kerns - setposition(f,kernoffset) - local coverage=readushort(f) - local nofglyphs=readushort(f) - if nofglyphs>0 then - local function get(offset) - setposition(f,kernoffset+offset) - local n=readushort(f) - if n==0 then - local k=readmathvalue(f) - if k==0 then - else - return { { kern=k } } - end - else - local l={} - for i=1,n do - l[i]={ height=readmathvalue(f) } - end - for i=1,n do - l[i].kern=readmathvalue(f) - end - l[n+1]={ kern=readmathvalue(f) } - return l - end - end - local kernsets={} - for i=1,nofglyphs do - local topright=readushort(f) - local topleft=readushort(f) - local bottomright=readushort(f) - local bottomleft=readushort(f) - kernsets[i]={ - topright=topright~=0 and topright or nil, - topleft=topleft~=0 and topleft or nil, - bottomright=bottomright~=0 and bottomright or nil, - bottomleft=bottomleft~=0 and bottomleft or nil, - } - end - coverage=readcoverage(f,kernoffset+coverage,true) - for i=1,nofglyphs do - local kernset=kernsets[i] - if next(kernset) then - local k=kernset.topright if k then kernset.topright=get(k) end - local k=kernset.topleft if k then kernset.topleft=get(k) end - local k=kernset.bottomright if k then kernset.bottomright=get(k) end - local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end - if next(kernset) then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if math then - math.kerns=kernset - else - glyph.math={ kerns=kernset } - end - end - end - end - end - end -end -local function readmathvariants(f,fontdata,offset) - setposition(f,offset) - local glyphs=fontdata.glyphs - local minoverlap=readushort(f) - local vcoverage=readushort(f) - local hcoverage=readushort(f) - local vnofglyphs=readushort(f) - local hnofglyphs=readushort(f) - local vconstruction=readcardinaltable(f,vnofglyphs,ushort) - local hconstruction=readcardinaltable(f,hnofglyphs,ushort) - fontdata.mathconstants.MinConnectorOverlap=minoverlap - local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) - if coverage~=0 and nofglyphs>0 then - local coverage=readcoverage(f,offset+coverage,true) - for i=1,nofglyphs do - local c=construction[i] - if c~=0 then - local index=coverage[i] - local glyph=glyphs[index] - local math=glyph.math - setposition(f,offset+c) - local assembly=readushort(f) - local nofvariants=readushort(f) - if nofvariants>0 then - local variants,v=nil,0 - for i=1,nofvariants do - local variant=readushort(f) - if variant==index then - elseif variants then - v=v+1 - variants[v]=variant - else - v=1 - variants={ variant } - end - skipshort(f) - end - if not variants then - elseif not math then - math={ [kvariants]=variants } - glyph.math=math - else - math[kvariants]=variants - end - end - if assembly~=0 then - setposition(f,offset+c+assembly) - local italic=readmathvalue(f) - local nofparts=readushort(f) - local parts={} - for i=1,nofparts do - local p={ - glyph=readushort(f), - start=readushort(f), - ["end"]=readushort(f), - advance=readushort(f), - } - local flags=readushort(f) - if band(flags,0x0001)~=0 then - p.extender=1 - end - parts[i]=p - end - if not math then - math={ - [kparts]=parts - } - glyph.math=math - else - math[kparts]=parts - end - if italic and italic~=0 then - math[kitalic]=italic - end - end - end - end - end - end - get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") - get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") -end -function readers.math(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) - if tableoffset then - local version=readulong(f) - local constants=readushort(f) - local glyphinfo=readushort(f) - local variants=readushort(f) - if constants==0 then - report("the math table of %a has no constants",fontdata.filename) - else - readmathconstants(f,fontdata,tableoffset+constants) - end - if glyphinfo~=0 then - readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) - end - if variants~=0 then - readmathvariants(f,fontdata,tableoffset+variants) - end - end -end -function readers.colr(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) - if tableoffset then - local version=readushort(f) - if version~=0 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) - return - end - if not fontdata.tables.cpal then - report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") - fontdata.colorpalettes={} - end - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local baseoffset=readulong(f) - local layeroffset=readulong(f) - local noflayers=readushort(f) - local layerrecords={} - local maxclass=0 - setposition(f,tableoffset+layeroffset) - for i=1,noflayers do - local slot=readushort(f) - local class=readushort(f) - if class<0xFFFF then - class=class+1 - if class>maxclass then - maxclass=class - end - end - layerrecords[i]={ - slot=slot, - class=class, - } - end - fontdata.maxcolorclass=maxclass - setposition(f,tableoffset+baseoffset) - for i=0,nofglyphs-1 do - local glyphindex=readushort(f) - local firstlayer=readushort(f) - local noflayers=readushort(f) - local t={} - for i=1,noflayers do - t[i]=layerrecords[firstlayer+i] - end - glyphs[glyphindex].colors=t - end - end - fontdata.hascolor=true -end -function readers.cpal(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) - if tableoffset then - local version=readushort(f) - local nofpaletteentries=readushort(f) - local nofpalettes=readushort(f) - local nofcolorrecords=readushort(f) - local firstcoloroffset=readulong(f) - local colorrecords={} - local palettes=readcardinaltable(f,nofpalettes,ushort) - if version==1 then - local palettettypesoffset=readulong(f) - local palettelabelsoffset=readulong(f) - local paletteentryoffset=readulong(f) - end - setposition(f,tableoffset+firstcoloroffset) - for i=1,nofcolorrecords do - local b,g,r,a=readbytes(f,4) - colorrecords[i]={ - r,g,b,a~=255 and a or nil, - } - end - for i=1,nofpalettes do - local p={} - local o=palettes[i] - for j=1,nofpaletteentries do - p[j]=colorrecords[o+j] - end - palettes[i]=p - end - fontdata.colorpalettes=palettes - end -end -local compress=gzip and gzip.compress -local compressed=compress and gzip.compressed -function readers.svg(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) - if tableoffset then - local version=readushort(f) - local glyphs=fontdata.glyphs - local indexoffset=tableoffset+readulong(f) - local reserved=readulong(f) - setposition(f,indexoffset) - local nofentries=readushort(f) - local entries={} - for i=1,nofentries do - entries[i]={ - first=readushort(f), - last=readushort(f), - offset=indexoffset+readulong(f), - length=readulong(f), - } - end - for i=1,nofentries do - local entry=entries[i] - setposition(f,entry.offset) - local data=readstring(f,entry.length) - if compressed and not compressed(data) then - data=compress(data) - end - entries[i]={ - first=entry.first, - last=entry.last, - data=data - } - end - fontdata.svgshapes=entries - end - fontdata.hascolor=true -end -function readers.sbix(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) - if tableoffset then - local version=readushort(f) - local flags=readushort(f) - local nofstrikes=readulong(f) - local strikes={} - local nofglyphs=fontdata.nofglyphs - for i=1,nofstrikes do - strikes[i]=readulong(f) - end - local shapes={} - local done=0 - for i=1,nofstrikes do - local strikeoffset=strikes[i]+tableoffset - setposition(f,strikeoffset) - strikes[i]={ - ppem=readushort(f), - ppi=readushort(f), - offset=strikeoffset - } - end - sort(strikes,function(a,b) - if b.ppem==a.ppem then - return b.ppi0 or fonts.handlers.typethree - for i=1,nofstrikes do - local strike=strikes[i] - local strikeppem=strike.ppem - local strikeppi=strike.ppi - local strikeoffset=strike.offset - setposition(f,strikeoffset) - for i=0,nofglyphs do - glyphs[i]=readulong(f) - end - local glyphoffset=glyphs[0] - for i=0,nofglyphs-1 do - local nextoffset=glyphs[i+1] - if not shapes[i] then - local datasize=nextoffset-glyphoffset - if datasize>0 then - setposition(f,strikeoffset+glyphoffset) - local x=readshort(f) - local y=readshort(f) - local tag=readtag(f) - local size=datasize-8 - local data=nil - local offset=nil - if delayed then - offset=getposition(f) - data=nil - else - data=readstring(f,size) - size=nil - end - shapes[i]={ - x=x, - y=y, - o=offset, - s=size, - data=data, - } - done=done+1 - if done==nofglyphs then - break - end - end - end - glyphoffset=nextoffset - end - end - fontdata.pngshapes=shapes - end -end -do - local function getmetrics(f) - return { - ascender=readinteger(f), - descender=readinteger(f), - widthmax=readuinteger(f), - caretslopedumerator=readinteger(f), - caretslopedenominator=readinteger(f), - caretoffset=readinteger(f), - minorigin=readinteger(f), - minadvance=readinteger(f), - maxbefore=readinteger(f), - minafter=readinteger(f), - pad1=readinteger(f), - pad2=readinteger(f), - } - end - local function getbigmetrics(f) - return { - height=readuinteger(f), - width=readuinteger(f), - horiBearingX=readinteger(f), - horiBearingY=readinteger(f), - horiAdvance=readuinteger(f), - vertBearingX=readinteger(f), - vertBearingY=readinteger(f), - vertAdvance=readuinteger(f), - } - end - local function getsmallmetrics(f) - return { - height=readuinteger(f), - width=readuinteger(f), - bearingX=readinteger(f), - bearingY=readinteger(f), - advance=readuinteger(f), - } - end - function readers.cblc(f,fontdata,specification) - local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) - if not ctdttableoffset then - return - end - local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) - if cblctableoffset then - local majorversion=readushort(f) - local minorversion=readushort(f) - local nofsizetables=readulong(f) - local sizetables={} - local shapes={} - local subtables={} - for i=1,nofsizetables do - sizetables[i]={ - subtables=readulong(f), - indexsize=readulong(f), - nofsubtables=readulong(f), - colorref=readulong(f), - hormetrics=getmetrics(f), - vermetrics=getmetrics(f), - firstindex=readushort(f), - lastindex=readushort(f), - ppemx=readbyte(f), - ppemy=readbyte(f), - bitdepth=readbyte(f), - flags=readbyte(f), - } - end - sort(sizetables,function(a,b) - if b.ppemx==a.ppemx then - return b.bitdepth0 or fonts.handlers.typethree - for index,subtable in sortedhash(shapes) do - if type(subtable)=="table" then - local data=nil - local size=nil - local metrics=default - local format=subtable.format - local offset=subtable.offsets[index] - setposition(f,offset) - if format==17 then - metrics=getsmallmetrics(f) - size=true - elseif format==18 then - metrics=getbigmetrics(f) - size=true - elseif format==19 then - metrics=subtable.metrics - size=true - else - end - if size then - size=readulong(f) - if delayed then - offset=getposition(f) - data=nil - else - offset=nil - data=readstring(f,size) - size=nil - end - else - offset=nil - end - local x=metrics.width - local y=metrics.height - shapes[index]={ - x=x, - y=y, - o=offset, - s=size, - data=data, - } - local glyph=glyphs[index] - if not glyph.boundingbox then - local width=glyph.width - local height=width*y/x - glyph.boundingbox={ 0,0,width,height } - end - else - shapes[index]={ - x=0, - y=0, - data="", - } - end - end - fontdata.pngshapes=shapes - end - end - function readers.cbdt(f,fontdata,specification) - end -end -function readers.stat(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"stat",true) - if tableoffset then - local extras=fontdata.extras - local version=readulong(f) - local axissize=readushort(f) - local nofaxis=readushort(f) - local axisoffset=readulong(f) - local nofvalues=readushort(f) - local valuesoffset=readulong(f) - local fallbackname=extras[readushort(f)] - local axis={} - local values={} - setposition(f,tableoffset+axisoffset) - for i=1,nofaxis do - local tag=readtag(f) - axis[i]={ - tag=tag, - name=lower(extras[readushort(f)] or tag), - ordering=readushort(f), - variants={} - } - end - setposition(f,tableoffset+valuesoffset) - for i=1,nofvalues do - values[i]=readushort(f) - end - for i=1,nofvalues do - setposition(f,tableoffset+valuesoffset+values[i]) - local format=readushort(f) - local index=readushort(f)+1 - local flags=readushort(f) - local name=lower(extras[readushort(f)] or "no name") - local value=readfixed(f) - local variant - if format==1 then - variant={ - flags=flags, - name=name, - value=value, - } - elseif format==2 then - variant={ - flags=flags, - name=name, - value=value, - minimum=readfixed(f), - maximum=readfixed(f), - } - elseif format==3 then - variant={ - flags=flags, - name=name, - value=value, - link=readfixed(f), - } - end - insert(axis[index].variants,variant) - end - sort(axis,function(a,b) - return a.ordering=lastto then - else - values[#values+1]={ from,to } - lastfrom,lastto=from,to - end - end - nofvalues=#values - if nofvalues>2 then - local some=values[1] - if some[1]==-1 and some[2]==-1 then - some=values[nofvalues] - if some[1]==1 and some[2]==1 then - for i=2,nofvalues-1 do - some=values[i] - if some[1]==0 and some[2]==0 then - return values - end - end - end - end - end - return false - end - local version=readulong(f) - local reserved=readushort(f) - local nofaxis=readushort(f) - local segments={} - for i=1,nofaxis do - segments[i]=collect() - end - setvariabledata(fontdata,"segments",segments) - end -end -function readers.fvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"fvar",true) - if tableoffset then - local version=readulong(f) - local offsettoaxis=tableoffset+readushort(f) - local reserved=skipshort(f) - local nofaxis=readushort(f) - local sizeofaxis=readushort(f) - local nofinstances=readushort(f) - local sizeofinstances=readushort(f) - local extras=fontdata.extras - local axis={} - local instances={} - setposition(f,offsettoaxis) - for i=1,nofaxis do - axis[i]={ - tag=readtag(f), - minimum=readfixed(f), - default=readfixed(f), - maximum=readfixed(f), - flags=readushort(f), - name=lower(extras[readushort(f)] or "bad name"), - } - local n=sizeofaxis-20 - if n>0 then - skipbytes(f,n) - elseif n<0 then - end - end - local nofbytes=2+2+2+nofaxis*4 - local readpsname=nofbytes<=sizeofinstances - local skippable=sizeofinstances-nofbytes - for i=1,nofinstances do - local subfamid=readushort(f) - local flags=readushort(f) - local values={} - for i=1,nofaxis do - values[i]={ - axis=axis[i].tag, - value=readfixed(f), - } - end - local psnameid=readpsname and readushort(f) or 0xFFFF - if subfamid==2 or subfamid==17 then - elseif subfamid==0xFFFF then - subfamid=nil - elseif subfamid<=256 or subfamid>=32768 then - subfamid=nil - end - if psnameid==6 then - elseif psnameid==0xFFFF then - psnameid=nil - elseif psnameid<=256 or psnameid>=32768 then - psnameid=nil - end - instances[i]={ - subfamily=extras[subfamid], - psname=psnameid and extras[psnameid] or nil, - values=values, - } - if skippable>0 then - skipbytes(f,skippable) - end - end - setvariabledata(fontdata,"axis",axis) - setvariabledata(fontdata,"instances",instances) - end -end -function readers.hvar(f,fontdata,specification) - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) - if not tableoffset then - return - end - local version=readulong(f) - local variationoffset=tableoffset+readulong(f) - local advanceoffset=tableoffset+readulong(f) - local lsboffset=tableoffset+readulong(f) - local rsboffset=tableoffset+readulong(f) - local regions={} - local variations={} - local innerindex={} - local outerindex={} - if variationoffset>0 then - regions,deltas=readvariationdata(f,variationoffset,factors) - end - if not regions then - return - end - if advanceoffset>0 then - setposition(f,advanceoffset) - local format=readushort(f) - local mapcount=readushort(f) - local entrysize=rshift(band(format,0x0030),4)+1 - local nofinnerbits=band(format,0x000F)+1 - local innermask=lshift(1,nofinnerbits)-1 - local readcardinal=read_cardinal[entrysize] - for i=0,mapcount-1 do - local mapdata=readcardinal(f) - outerindex[i]=rshift(mapdata,nofinnerbits) - innerindex[i]=band(mapdata,innermask) - end - setvariabledata(fontdata,"hvarwidths",true) - local glyphs=fontdata.glyphs - for i=0,fontdata.nofglyphs-1 do - local glyph=glyphs[i] - local width=glyph.width - if width then - local outer=outerindex[i] or 0 - local inner=innerindex[i] or i - if outer and inner then - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local deltaw=0 - for i=1,#scales do - local di=d[i] - if di then - deltaw=deltaw+scales[i]*di - else - break - end - end - glyph.width=width+round(deltaw) - end - end - end - end - end - end -end -function readers.vvar(f,fontdata,specification) - if not specification.variable then - return - end -end -function readers.mvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) - if tableoffset then - local version=readulong(f) - local reserved=skipshort(f,1) - local recordsize=readushort(f) - local nofrecords=readushort(f) - local offsettostore=tableoffset+readushort(f) - local dimensions={} - local factors=specification.factors - if factors then - local regions,deltas=readvariationdata(f,offsettostore,factors) - for i=1,nofrecords do - local tag=readtag(f) - local var=variabletags[tag] - if var then - local outer=readushort(f) - local inner=readushort(f) - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local dd=0 - for i=1,#scales do - dd=dd+scales[i]*d[i] - end - var(fontdata,round(dd)) - end - end - else - skipshort(f,2) - end - if recordsize>8 then - skipbytes(recordsize-8) - end - end - end - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] --- - -if not modules then modules={} end modules ['font-oup']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type=next,type -local P,R,S=lpeg.P,lpeg.R,lpeg.S -local lpegmatch=lpeg.match -local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack -local formatters=string.formatters -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local tohash=table.tohash -local setmetatableindex=table.setmetatableindex -local report_error=logs.reporter("otf reader","error") -local report_markwidth=logs.reporter("otf reader","markwidth") -local report_cleanup=logs.reporter("otf reader","cleanup") -local report_optimizations=logs.reporter("otf reader","merges") -local report_unicodes=logs.reporter("otf reader","unicodes") -local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) -local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end) -local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end) -local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end) -local readers=fonts.handlers.otf.readers -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local f_private=formatters["P%05X"] -local f_unicode=formatters["U%05X"] -local f_index=formatters["I%05X"] -local f_character_y=formatters["%C"] -local f_character_n=formatters["[ %C ]"] -local check_duplicates=true -local check_soft_hyphen=true -directives.register("otf.checksofthyphen",function(v) - check_soft_hyphen=v -end) -local function replaced(list,index,replacement) - if type(list)=="number" then - return replacement - elseif type(replacement)=="table" then - local t={} - local n=index-1 - for i=1,n do - t[i]=list[i] - end - for i=1,#replacement do - n=n+1 - t[n]=replacement[i] - end - for i=index+1,#list do - n=n+1 - t[n]=list[i] - end - else - list[index]=replacement - return list - end -end -local function unifyresources(fontdata,indices) - local descriptions=fontdata.descriptions - local resources=fontdata.resources - if not descriptions or not resources then - return - end - local nofindices=#indices - local variants=fontdata.resources.variants - if variants then - for selector,unicodes in next,variants do - for unicode,index in next,unicodes do - unicodes[unicode]=indices[index] - end - end - end - local function remark(marks) - if marks then - local newmarks={} - for k,v in next,marks do - local u=indices[k] - if u then - newmarks[u]=v - elseif trace_optimizations then - report_optimizations("discarding mark %i",k) - end - end - return newmarks - end - end - local marks=resources.marks - if marks then - resources.marks=remark(marks) - end - local markclasses=resources.markclasses - if markclasses then - for class,marks in next,markclasses do - markclasses[class]=remark(marks) - end - end - local marksets=resources.marksets - if marksets then - for class,marks in next,marksets do - marksets[class]=remark(marks) - end - end - local done={} - local duplicates=check_duplicates and resources.duplicates - if duplicates and not next(duplicates) then - duplicates=false - end - local function recover(cover) - for i=1,#cover do - local c=cover[i] - if not done[c] then - local t={} - for k,v in next,c do - local ug=indices[k] - if ug then - t[ug]=v - else - report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) - end - end - cover[i]=t - done[c]=d - end - end - end - local function recursed(c,kind) - local t={} - for g,d in next,c do - if type(d)=="table" then - local ug=indices[g] - if ug then - t[ug]=recursed(d,kind) - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) - end - else - t[g]=indices[d] - end - end - return t - end - local function unifythem(sequences) - if not sequences then - return - end - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gsub_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - local ud1=indices[d1] - if ud1 then - t1[ug1]=ud1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=ud1 - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=indices[d1] - else - report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_pair" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - local ug2=indices[g2] - if ug2 then - t2[ug2]=d2 - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) - end - end - done[d1]=t2 - end - t1[ug1]=t2 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gsub_ligature" then - local c=step.coverage - if c then - step.coverage=recursed(c,kind) - end - elseif kind=="gsub_alternate" or kind=="gsub_multiple" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - for i=1,#d1 do - local d1i=d1[i] - local d1u=indices[d1i] - if d1u then - d1[i]=d1u - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) - end - end - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - for i=1,#d1 do - local d1i=d1[i] - local d1u=indices[d1i] - if d1u then - d1[i]=d1u - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) - end - end - t1[indices[g1]]=d1 - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=d1 - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - done[c]=t1 - end - step.coverage=t1 - end - local c=step.baseclasses - if c then - local t1=done[c] - if not t1 then - for g1,d1 in next,c do - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - local ug2=indices[g2] - if ug2 then - t2[ug2]=d2 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) - end - end - done[d1]=t2 - end - c[g1]=t2 - end - done[c]=c - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - else - report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) - end - end - else - for g1,d1 in next,c do - local ug1=indices[g1] - if ug1 then - t1[ug1]=d1 - else - report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) - end - end - end - done[c]=t1 - end - step.coverage=t1 - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before if before then recover(before) end - local after=rule.after if after then recover(after) end - local current=rule.current if current then recover(current) end - local replacements=rule.replacements - if replacements then - if not done[replacements] then - local r={} - for k,v in next,replacements do - r[indices[k]]=indices[v] - end - rule.replacements=r - done[replacements]=r - end - end - end - end - end - end - end - end - unifythem(resources.sequences) - unifythem(resources.sublookups) -end -local function copyduplicates(fontdata) - if check_duplicates then - local descriptions=fontdata.descriptions - local resources=fontdata.resources - local duplicates=resources.duplicates - if check_soft_hyphen then - local ds=descriptions[0xAD] - if not ds or ds.width==0 then - if ds then - descriptions[0xAD]=nil - if trace_unicodes then - report_unicodes("patching soft hyphen") - end - else - if trace_unicodes then - report_unicodes("adding soft hyphen") - end - end - if not duplicates then - duplicates={} - resources.duplicates=duplicates - end - local dh=duplicates[0x2D] - if dh then - dh[#dh+1]={ [0xAD]=true } - else - duplicates[0x2D]={ [0xAD]=true } - end - end - end - if duplicates then - for u,d in next,duplicates do - local du=descriptions[u] - if du then - local t={ f_character_y(u),"@",f_index(du.index),"->" } - local n=0 - local m=25 - for u in next,d do - if descriptions[u] then - if n0 then - t={} - n=0 - local loops=0 - while true do - loops=loops+1 - local old=nofmissing - for i=1,#ligatures do - recursed(ligatures[i]) - end - if nofmissing<=0 then - if trace_unicodes then - report_unicodes("all missings done in %s loops",loops) - end - return - elseif old==nofmissing then - break - end - end - t=nil - n=0 - end - if trace_unicodes and nofmissing>0 then - local done={} - for i,r in next,missing do - if r then - local data=descriptions[i] - local name=data and data.name or f_index(i) - if not ignore[name] then - done[name]=true - end - end - end - if next(done) then - report_unicodes("not unicoded: % t",sortedkeys(done)) - end - end -end -local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF -local function unifymissing(fontdata) - if not fonts.mappings then - require("font-map") - require("font-agl") - end - local unicodes={} - local resources=fontdata.resources - resources.unicodes=unicodes - for unicode,d in next,fontdata.descriptions do - if unicode=puafirst and unicode<=pualast then - else - local name=d.name - if name then - unicodes[name]=unicode - end - end - else - end - end - fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) - resources.unicodes=nil -end -local function unifyglyphs(fontdata,usenames) - local private=fontdata.private or privateoffset - local glyphs=fontdata.glyphs - local indices={} - local descriptions={} - local names=usenames and {} - local resources=fontdata.resources - local zero=glyphs[0] - local zerocode=zero.unicode - if not zerocode then - zerocode=private - zero.unicode=zerocode - private=private+1 - end - descriptions[zerocode]=zero - if names then - local name=glyphs[0].name or f_private(zerocode) - indices[0]=name - names[name]=zerocode - else - indices[0]=zerocode - end - if names then - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - elseif unicode>=firstprivate then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - elseif descriptions[unicode] then - unicode=private - local name=glyph.name or f_private(unicode) - indices[index]=name - names[name]=unicode - private=private+1 - else - local name=glyph.name or f_unicode(unicode) - indices[index]=name - names[name]=unicode - end - descriptions[unicode]=glyph - end - elseif trace_unicodes then - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=firstprivate then - local name=glyph.name - if name then - report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) - else - report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) - end - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name - if name then - report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) - else - report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) - end - indices[index]=unicode - elseif descriptions[unicode] then - local name=glyph.name - if name then - report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) - else - report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) - end - unicode=private - indices[index]=unicode - private=private+1 - else - indices[index]=unicode - end - descriptions[unicode]=glyph - end - else - for index=1,#glyphs do - local glyph=glyphs[index] - local unicode=glyph.unicode - if not unicode then - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=firstprivate then - local name=glyph.name - unicode=private - indices[index]=unicode - private=private+1 - elseif unicode>=puafirst and unicode<=pualast then - local name=glyph.name - indices[index]=unicode - elseif descriptions[unicode] then - local name=glyph.name - unicode=private - indices[index]=unicode - private=private+1 - else - indices[index]=unicode - end - descriptions[unicode]=glyph - end - end - for index=1,#glyphs do - local math=glyphs[index].math - if math then - local list=math.vparts - if list then - for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end - end - local list=math.hparts - if list then - for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end - end - local list=math.vvariants - if list then - for i=1,#list do list[i]=indices[list[i]] end - end - local list=math.hvariants - if list then - for i=1,#list do list[i]=indices[list[i]] end - end - end - end - local colorpalettes=resources.colorpalettes - if colorpalettes then - for index=1,#glyphs do - local colors=glyphs[index].colors - if colors then - for i=1,#colors do - local c=colors[i] - c.slot=indices[c.slot] - end - end - end - end - fontdata.private=private - fontdata.glyphs=nil - fontdata.names=names - fontdata.descriptions=descriptions - fontdata.hashmethod=hashmethod - return indices,names -end -local p_crappyname do - local p_hex=R("af","AF","09") - local p_digit=R("09") - local p_done=S("._-")^0+P(-1) - local p_alpha=R("az","AZ") - local p_ALPHA=R("AZ") - p_crappyname=( - lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1 -+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1 -+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1 -+p_digit*p_hex^3+p_alpha*p_digit^1 -+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1 - )*p_done -end -local forcekeep=false -directives.register("otf.keepnames",function(v) - report_cleanup("keeping weird glyph names, expect larger files and more memory usage") - forcekeep=v -end) -local function stripredundant(fontdata) - local descriptions=fontdata.descriptions - if descriptions then - local n=0 - local c=0 - if (not context and fonts.privateoffsets.keepnames) or forcekeep then - for unicode,d in next,descriptions do - if d.class=="base" then - d.class=nil - c=c+1 - end - end - else - for unicode,d in next,descriptions do - local name=d.name - if name and lpegmatch(p_crappyname,name) then - d.name=nil - n=n+1 - end - if d.class=="base" then - d.class=nil - c=c+1 - end - end - end - if trace_cleanup then - if n>0 then - report_cleanup("%s bogus names removed (verbose unicode)",n) - end - if c>0 then - report_cleanup("%s base class tags removed (default is base)",c) - end - end - end -end -readers.stripredundant=stripredundant -function readers.getcomponents(fontdata) - local resources=fontdata.resources - if resources then - local sequences=resources.sequences - if sequences then - local collected={} - for i=1,#sequences do - local sequence=sequences[i] - if sequence.type=="gsub_ligature" then - local steps=sequence.steps - if steps then - local l={} - local function traverse(p,k,v) - if k=="ligature" then - collected[v]={ unpack(l) } - else - insert(l,k) - for k,vv in next,v do - traverse(p,k,vv) - end - remove(l) - end - end - for i=1,#steps do - local c=steps[i].coverage - if c then - for k,v in next,c do - traverse(k,k,v) - end - end - end - end - end - end - if next(collected) then - while true do - local done=false - for k,v in next,collected do - for i=1,#v do - local vi=v[i] - if vi==k then - collected[k]=nil - break - else - local c=collected[vi] - if c then - done=true - local t={} - local n=i-1 - for j=1,n do - t[j]=v[j] - end - for j=1,#c do - n=n+1 - t[n]=c[j] - end - for j=i+1,#v do - n=n+1 - t[n]=v[j] - end - collected[k]=t - break - end - end - end - end - if not done then - break - end - end - return collected - end - end - end -end -readers.unifymissing=unifymissing -function readers.rehash(fontdata,hashmethod) - if not (fontdata and fontdata.glyphs) then - return - end - if hashmethod=="indices" then - fontdata.hashmethod="indices" - elseif hashmethod=="names" then - fontdata.hashmethod="names" - local indices=unifyglyphs(fontdata,true) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - else - fontdata.hashmethod="unicodes" - local indices=unifyglyphs(fontdata) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - stripredundant(fontdata) - end -end -function readers.checkhash(fontdata) - local hashmethod=fontdata.hashmethod - if hashmethod=="unicodes" then - fontdata.names=nil - elseif hashmethod=="names" and fontdata.names then - unifyresources(fontdata,fontdata.names) - copyduplicates(fontdata) - fontdata.hashmethod="unicodes" - fontdata.names=nil - else - readers.rehash(fontdata,"unicodes") - end -end -function readers.addunicodetable(fontdata) - local resources=fontdata.resources - local unicodes=resources.unicodes - if not unicodes then - local descriptions=fontdata.descriptions - if descriptions then - unicodes={} - resources.unicodes=unicodes - for u,d in next,descriptions do - local n=d.name - if n then - unicodes[n]=u - end - end - end - end -end -local concat,sort=table.concat,table.sort -local next,type,tostring=next,type,tostring -local criterium=1 -local threshold=0 -local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local function tabstr_normal(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if type(v)=="table" then - s[n]=k..">"..tabstr_normal(v) - elseif v==true then - s[n]=k.."+" - elseif v then - s[n]=k.."="..v - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_flat(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - s[n]=k.."="..v - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_mixed(t) - local s={} - local n=#t - if n==0 then - return "" - elseif n==1 then - local k=t[1] - if k==true then - return "++" - elseif k==false then - return "--" - else - return tostring(k) - end - else - for i=1,n do - local k=t[i] - if k==true then - s[i]="++" - elseif k==false then - s[i]="--" - else - s[i]=k - end - end - return concat(s,",") - end -end -local function tabstr_boolean(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if v then - s[n]=k.."+" - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -function readers.pack(data) - if data then - local h,t,c={},{},{} - local hh,tt,cc={},{},{} - local nt,ntt=0,0 - local function pack_normal(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_normal_cc(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - v[1]=0 - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_flat(v) - local tag=tabstr_flat(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_indexed(v) - local tag=concat(v," ") - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_mixed(v) - local tag=tabstr_mixed(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_boolean(v) - local tag=tabstr_boolean(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_final(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end - end - end - local function pack_final_cc(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end - end - end - local function success(stage,pass) - if nt==0 then - if trace_loading or trace_packing then - report_otf("pack quality: nothing to pack") - end - return false - elseif nt>=threshold then - local one=0 - local two=0 - local rest=0 - if pass==1 then - for k,v in next,c do - if v==1 then - one=one+1 - elseif v==2 then - two=two+1 - else - rest=rest+1 - end - end - else - for k,v in next,cc do - if v>20 then - rest=rest+1 - elseif v>10 then - two=two+1 - else - one=one+1 - end - end - data.tables=tt - end - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", - stage,pass,one+two+rest,one,two,rest,criterium) - end - return true - else - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", - stage,pass,nt,threshold) - end - return false - end - end - local function packers(pass) - if pass==1 then - return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc - else - return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc - end - end - local resources=data.resources - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local chardata=characters and characters.data - local descriptions=data.descriptions or data.glyphs - if not descriptions then - return - end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 1, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local boundingbox=description.boundingbox - if boundingbox then - description.boundingbox=pack_indexed(boundingbox) - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - for tag,kern in next,kerns do - kerns[tag]=pack_normal(kern) - end - end - end - end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format~="pair" then - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - elseif step.shared then - local shared={} - for g1,d1 in next,c do - for g2,d2 in next,d1 do - if not shared[d2] then - local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end - local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end - shared[d2]=true - end - end - end - if pass==2 then - step.shared=nil - end - else - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end - local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end - end - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - if d1 and d1~=true then - c[g1]=pack_indexed(d1) - end - end - else - step.coverage=pack_normal(c) - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local f=d1[2] if f then d1[2]=pack_indexed(f) end - local s=d1[3] if s then d1[3]=pack_indexed(s) end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_indexed(d2) - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - for g3,d3 in next,d2 do - d2[g3]=pack_indexed(d3) - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.replacements if r then rule.replacements=pack_flat (r) end - end - end - end - end - if order then - sequence.order=pack_indexed(order) - end - if features then - for script,feature in next,features do - features[script]=pack_normal(feature) - end - end - if flags then - sequence.flags=pack_normal(flags) - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if features then - for k,list in next,features do - for feature,spec in next,list do - list[feature]=pack_normal(spec) - end - end - end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - p[j]=pack_indexed(p[j]) - end - end - end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - v[j]=pack_normal(v[j]) - end - end - end - local function packdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - for j=1,#d do - d[j]=pack_indexed(d[j]) - end - di.regions=pack_indexed(di.regions) - end - end - local regions=main.regions - if regions then - for i=1,#regions do - local r=regions[i] - for j=1,#r do - r[j]=pack_normal(r[j]) - end - end - end - end - end - packdeltas(variable.global) - packdeltas(variable.horizontal) - packdeltas(variable.vertical) - packdeltas(variable.metrics) - end - if not success(1,pass) then - return - end - end - if nt>0 then - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 2, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local math=description.math - if math then - local kerns=math.kerns - if kerns then - math.kerns=pack_normal(kerns) - end - end - end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then rule.before=pack_normal(r) end - local r=rule.after if r then rule.after=pack_normal(r) end - local r=rule.current if r then rule.current=pack_normal(r) end - end - end - end - end - if features then - sequence.features=pack_normal(features) - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if variable then - local function unpackdeltas(main) - if main then - local regions=main.regions - if regions then - main.regions=pack_normal(regions) - end - end - end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) - end - end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 3, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - c[g1]=pack_normal_cc(d1) - end - end - end - end - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - end - end - end -end -local unpacked_mt={ - __index=function(t,k) - t[k]=false - return k - end -} -function readers.unpack(data) - if data then - local tables=data.tables - if tables then - local resources=data.resources - local descriptions=data.descriptions or data.glyphs - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local unpacked={} - setmetatable(unpacked,unpacked_mt) - for unicode,description in next,descriptions do - local tv=tables[description.boundingbox] - if tv then - description.boundingbox=tv - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - local tm=tables[kerns] - if tm then - math.kerns=tm - kerns=unpacked[tm] - end - if kerns then - for k,kern in next,kerns do - local tv=tables[kern] - if tv then - kerns[k]=tv - end - end - end - end - end - end - local function unpackthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - local markclass=sequence.markclass - if features then - local tv=tables[features] - if tv then - sequence.features=tv - features=tv - end - for script,feature in next,features do - local tv=tables[feature] - if tv then - features[script]=tv - end - end - end - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - d1=tv - end - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - d2=tv - end - local f=tables[d2[1]] if f then d2[1]=f end - local s=tables[d2[2]] if s then d2[2]=s end - end - end - else - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - else - local tv=tables[c] - if tv then - step.coverage=tv - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - d1=tv - c[g1]=d1 - end - local f=tables[d1[2]] if f then d1[2]=f end - local s=tables[d1[3]] if s then d1[3]=s end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d2=tv - d1[g2]=d2 - end - for g3,d3 in next,d2 do - local tv=tables[d2[g3]] - if tv then - d2[g3]=tv - end - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - if before then - local tv=tables[before] - if tv then - rule.before=tv - before=tv - end - for i=1,#before do - local tv=tables[before[i]] - if tv then - before[i]=tv - end - end - end - local after=rule.after - if after then - local tv=tables[after] - if tv then - rule.after=tv - after=tv - end - for i=1,#after do - local tv=tables[after[i]] - if tv then - after[i]=tv - end - end - end - local current=rule.current - if current then - local tv=tables[current] - if tv then - rule.current=tv - current=tv - end - for i=1,#current do - local tv=tables[current[i]] - if tv then - current[i]=tv - end - end - end - local replacements=rule.replacements - if replacements then - local tv=tables[replacements] - if tv then - rule.replacements=tv - end - end - end - end - end - end - if order then - local tv=tables[order] - if tv then - sequence.order=tv - end - end - if flags then - local tv=tables[flags] - if tv then - sequence.flags=tv - end - end - end - end - if sequences then - unpackthem(sequences) - end - if sublookups then - unpackthem(sublookups) - end - if features then - for k,list in next,features do - for feature,spec in next,list do - local tv=tables[spec] - if tv then - list[feature]=tv - end - end - end - end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - local tv=tables[p[j]] - if tv then - p[j]=tv - end - end - end - end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - local tv=tables[v[j]] - if tv then - v[j]=tv - end - end - end - end - local function unpackdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - local r=di.regions - for j=1,#d do - local tv=tables[d[j]] - if tv then - d[j]=tv - end - end - local tv=di.regions - if tv then - di.regions=tv - end - end - end - local regions=main.regions - if regions then - local tv=tables[regions] - if tv then - main.regions=tv - regions=tv - end - for i=1,#regions do - local r=regions[i] - for j=1,#r do - local tv=tables[r[j]] - if tv then - r[j]=tv - end - end - end - end - end - end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) - end - data.tables=nil - end - end -end -local mt={ - __index=function(t,k) - if k=="height" then - local ht=t.boundingbox[4] - return ht<0 and 0 or ht - elseif k=="depth" then - local dp=-t.boundingbox[2] - return dp<0 and 0 or dp - elseif k=="width" then - return 0 - elseif k=="name" then - return forcenotdef and ".notdef" - end - end -} -local function sameformat(sequence,steps,first,nofsteps,kind) - return true -end -local function mergesteps_1(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - if trace_optimizations then - report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - end - return 0 - end - end - end - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - if not target[k] then - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_2(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - if trace_optimizations then - report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - end - return 0 - end - end - end - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - for kk,vv in next,v do - if tk[kk]==nil then - tk[kk]=vv - end - end - else - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_3(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local coverage={} - for i=1,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=coverage[k] - if tk then - if trace_optimizations then - report_optimizations("quitting merge due to multiple checks") - end - return nofsteps - else - coverage[k]=v - end - end - end - end - local first=steps[1] - local baseclasses={} - for i=1,nofsteps do - local offset=i*10 - local step=steps[i] - for k,v in sortedhash(step.baseclasses) do - baseclasses[offset+k]=v - end - for k,v in next,step.coverage do - v[1]=offset+v[1] - end - end - first.baseclasses=baseclasses - first.coverage=coverage - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function nested(old,new) - for k,v in next,old do - if k=="ligature" then - if not new.ligature then - new.ligature=v - end - else - local n=new[k] - if n then - nested(v,n) - else - new[k]=v - end - end - end -end -local function mergesteps_4(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - nested(v,tk) - else - target[k]=v - end - end - end - end - lookup.nofsteps=1 - lookup.steps={ first } - return nofsteps-1 -end -local function mergesteps_5(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if trace_optimizations then - report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - end - local target=first.coverage - local hash=nil - for k,v in next,target do - hash=v[1] - break - end - for i=2,nofsteps do - local c=steps[i].coverage - if c then - for k,v in next,c do - local tk=target[k] - if tk then - if not tk[2] then - tk[2]=v[2] - end - if not tk[3] then - tk[3]=v[3] - end - else - target[k]=v - v[1]=hash - end - end - end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 -end -local function checkkerns(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=step.coverage - local kerns=true - for g1,d1 in next,coverage do - if d1==true then - elseif not d1 then - elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then - kerns=false - break - end - end - if kerns then - if trace_optimizations then - report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - end - local c={} - for g1,d1 in next,coverage do - if d1 and d1~=true then - c[g1]=d1[3] - end - end - step.coverage=c - step.format="move" - kerned=kerned+1 - end - end - end - return kerned -end -local function checkpairs(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - local function onlykerns(step) - local coverage=step.coverage - for g1,d1 in next,coverage do - for g2,d2 in next,d1 do - if d2[2] then - return false - else - local v=d2[1] - if v==true then - elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then - return false - end - end - end - end - return coverage - end - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=onlykerns(step) - if coverage then - if trace_optimizations then - report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - end - for g1,d1 in next,coverage do - local d={} - for g2,d2 in next,d1 do - local v=d2[1] - if v==true then - elseif v then - d[g2]=v[3] - end - end - coverage[g1]=d - end - step.format="move" - kerned=kerned+1 - end - end - end - return kerned -end -local compact_pairs=true -local compact_singles=true -local merge_pairs=true -local merge_singles=true -local merge_substitutions=true -local merge_alternates=true -local merge_multiples=true -local merge_ligatures=true -local merge_cursives=true -local merge_marks=true -directives.register("otf.compact.pairs",function(v) compact_pairs=v end) -directives.register("otf.compact.singles",function(v) compact_singles=v end) -directives.register("otf.merge.pairs",function(v) merge_pairs=v end) -directives.register("otf.merge.singles",function(v) merge_singles=v end) -directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end) -directives.register("otf.merge.alternates",function(v) merge_alternates=v end) -directives.register("otf.merge.multiples",function(v) merge_multiples=v end) -directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end) -directives.register("otf.merge.cursives",function(v) merge_cursives=v end) -directives.register("otf.merge.marks",function(v) merge_marks=v end) -function readers.compact(data) - if not data or data.compacted then - return - else - data.compacted=true - end - local resources=data.resources - local merged=0 - local kerned=0 - local allsteps=0 - local function compact(what) - local lookups=resources[what] - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local nofsteps=lookup.nofsteps - local kind=lookup.type - allsteps=allsteps+nofsteps - if nofsteps>1 then - local merg=merged - if kind=="gsub_single" then - if merge_substitutions then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_alternate" then - if merge_alternates then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_multiple" then - if merge_multiples then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_ligature" then - if merge_ligatures then - merged=merged+mergesteps_4(lookup) - end - elseif kind=="gpos_single" then - if merge_singles then - merged=merged+mergesteps_1(lookup,true) - end - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if merge_pairs then - merged=merged+mergesteps_2(lookup) - end - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - elseif kind=="gpos_cursive" then - if merge_cursives then - merged=merged+mergesteps_5(lookup) - end - elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then - if merge_marks then - merged=merged+mergesteps_3(lookup) - end - end - if merg~=merged then - lookup.merged=true - end - elseif nofsteps==1 then - local kern=kerned - if kind=="gpos_single" then - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - end - if kern~=kerned then - end - end - end - elseif trace_optimizations then - report_optimizations("no lookups in %a",what) - end - end - compact("sequences") - compact("sublookups") - if trace_optimizations then - if merged>0 then - report_optimizations("%i steps of %i removed due to merging",merged,allsteps) - end - if kerned>0 then - report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) - end - end -end -local function mergesteps(t,k) - if k=="merged" then - local merged={} - for i=1,#t do - local step=t[i] - local coverage=step.coverage - for k in next,coverage do - local m=merged[k] - if m then - m[2]=i - else - merged[k]={ i,i } - end - end - end - t.merged=merged - return merged - end -end -local function checkmerge(sequence) - local steps=sequence.steps - if steps then - setmetatableindex(steps,mergesteps) - end -end -local function checkflags(sequence,resources) - if not sequence.skiphash then - local flags=sequence.flags - if flags then - local skipmark=flags[1] - local skipligature=flags[2] - local skipbase=flags[3] - local markclass=sequence.markclass - local skipsome=skipmark or skipligature or skipbase or markclass or false - if skipsome then - sequence.skiphash=setmetatableindex(function(t,k) - local c=resources.classes[k] - local v=c==skipmark - or (markclass and c=="mark" and not markclass[k]) - or c==skipligature - or c==skipbase - or false - t[k]=v - return v - end) - else - sequence.skiphash=false - end - else - sequence.skiphash=false - end - end -end -local function checksteps(sequence) - local steps=sequence.steps - if steps then - for i=1,#steps do - steps[i].index=i - end - end -end -if fonts.helpers then - fonts.helpers.checkmerge=checkmerge - fonts.helpers.checkflags=checkflags - fonts.helpers.checksteps=checksteps -end -function readers.expand(data) - if not data or data.expanded then - return - else - data.expanded=true - end - local resources=data.resources - local sublookups=resources.sublookups - local sequences=resources.sequences - local markclasses=resources.markclasses - local descriptions=data.descriptions - if descriptions then - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local basename=trace_markwidth and file.basename(resources.filename) - for u,d in next,descriptions do - local bb=d.boundingbox - local wd=d.width - if not wd then - d.width=defaultwidth - elseif trace_markwidth and wd~=0 and d.class=="mark" then - report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) - end - if bb then - local ht=bb[4] - local dp=-bb[2] - if ht==0 or ht<0 then - else - d.height=ht - end - if dp==0 or dp<0 then - else - d.depth=dp - end - end - end - end - local function expandlookups(sequences) - if sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local nofsteps=sequence.nofsteps - local kind=sequence.type - local markclass=sequence.markclass - if markclass then - if not markclasses then - report_warning("missing markclasses") - sequence.markclass=false - else - sequence.markclass=markclasses[markclass] - end - end - for i=1,nofsteps do - local step=steps[i] - local baseclasses=step.baseclasses - if baseclasses then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=baseclasses[v[1]] - end - elseif kind=="gpos_cursive" then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=coverage - end - end - local rules=step.rules - if rules then - local rulehash={ n=0 } - local rulesize=0 - local coverage={} - local lookuptype=sequence.type - local nofrules=#rules - step.coverage=coverage - for currentrule=1,nofrules do - local rule=rules[currentrule] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups then - for i=1,#lookups do - local lookups=lookups[i] - if lookups then - for k,v in next,lookups do - local lookup=sublookups[v] - if lookup then - lookups[k]=lookup - if not subtype then - subtype=lookup.type - end - else - end - end - end - end - end - if sequence[1] then - sequence.n=#sequence - local ruledata={ - currentrule, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - rulesize=rulesize+1 - rulehash[rulesize]=ruledata - rulehash.n=rulesize - if true then - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - local n=#cu+1 - cu[n]=ruledata - cu.n=n - else - coverage[unic]={ ruledata,n=1 } - end - end - else - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - else - coverage[unic]=rulehash - end - end - end - end - end - end - end - checkmerge(sequence) - checkflags(sequence,resources) - checksteps(sequence) - end - end - end - end - expandlookups(sequences) - expandlookups(sublookups) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] --- - -if not modules then modules={} end modules ['font-otl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local lower=string.lower -local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack -local abs=math.abs -local derivetable=table.derive -local formatters=string.formatters -local setmetatableindex=table.setmetatableindex -local allocate=utilities.storage.allocate -local registertracker=trackers.register -local registerdirective=directives.register -local starttiming=statistics.starttiming -local stoptiming=statistics.stoptiming -local elapsedtime=statistics.elapsedtime -local findbinfile=resolvers.findbinfile -local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) -local trace_features=false registertracker("otf.features",function(v) trace_features=v end) -local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) -local report_otf=logs.reporter("fonts","otf loading") -local fonts=fonts -local otf=fonts.handlers.otf -otf.version=3.111 -otf.cache=containers.define("fonts","otl",otf.version,true) -otf.svgcache=containers.define("fonts","svg",otf.version,true) -otf.pngcache=containers.define("fonts","png",otf.version,true) -otf.pdfcache=containers.define("fonts","pdf",otf.version,true) -otf.mpscache=containers.define("fonts","mps",otf.version,true) -otf.svgenabled=false -otf.pngenabled=false -local otfreaders=otf.readers -local hashes=fonts.hashes -local definers=fonts.definers -local readers=fonts.readers -local constructors=fonts.constructors -local otffeatures=constructors.features.otf -local registerotffeature=otffeatures.register -local otfenhancers=constructors.enhancers.otf -local registerotfenhancer=otfenhancers.register -local forceload=false -local cleanup=0 -local syncspace=true -local forcenotdef=false -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -local wildcard="*" -local default="dflt" -local formats=fonts.formats -formats.otf="opentype" -formats.ttf="truetype" -formats.ttc="truetype" -registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end) -registerdirective("fonts.otf.loader.force",function(v) forceload=v end) -registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) -registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) -registerotfenhancer("check extra features",function() end) -local checkmemory=utilities.lua and utilities.lua.checkmemory -local threshold=100 -local tracememory=false -registertracker("fonts.otf.loader.memory",function(v) tracememory=v end) -if not checkmemory then - local collectgarbage=collectgarbage - checkmemory=function(previous,threshold) - local current=collectgarbage("count") - if previous then - local checked=(threshold or 64)*1024 - if current-previous>checked then - collectgarbage("collect") - current=collectgarbage("count") - end - end - return current - end -end -function otf.load(filename,sub,instance) - local base=file.basename(file.removesuffix(filename)) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if sub=="" then - sub=false - end - local hash=name - if sub then - hash=hash.."-"..sub - end - if instance then - hash=hash.."-"..instance - end - hash=containers.cleanname(hash) - local data=containers.read(otf.cache,hash) - local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion - if forceload then - report_otf("forced reload of %a due to hard coded flag",filename) - reload=true - end - if reload then - report_otf("loading %a, hash %a",filename,hash) - starttiming(otfreaders,true) - data=otfreaders.loadfont(filename,sub or 1,instance) - if data then - local used=checkmemory() - local resources=data.resources - local svgshapes=resources.svgshapes - local pngshapes=resources.pngshapes - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - if svgshapes then - resources.svgshapes=nil - if otf.svgenabled then - local timestamp=os.date() - containers.write(otf.svgcache,hash,{ - svgshapes=svgshapes, - timestamp=timestamp, - }) - data.properties.svg={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - if pngshapes then - resources.pngshapes=nil - if otf.pngenabled then - local timestamp=os.date() - containers.write(otf.pngcache,hash,{ - pngshapes=pngshapes, - timestamp=timestamp, - }) - data.properties.png={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - otfreaders.compact(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.rehash(data,"unicodes") - otfreaders.addunicodetable(data) - otfreaders.extend(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.pack(data) - report_otf("loading done") - report_otf("saving %a in cache",filename) - data=containers.write(otf.cache,hash,data) - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - stoptiming(otfreaders) - if elapsedtime then - report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) - end - if cleanup>3 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - data=containers.read(otf.cache,hash) - if cleanup>2 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - else - stoptiming(otfreaders) - data=nil - report_otf("loading failed due to read error") - end - end - if data then - if trace_defining then - report_otf("loading from cache using hash %a",hash) - end - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - data.metadata.math=data.resources.mathconstants - local classes=data.resources.classes - if not classes then - local descriptions=data.descriptions - classes=setmetatableindex(function(t,k) - local d=descriptions[k] - local v=(d and d.class or "base") or false - t[k]=v - return v - end) - data.resources.classes=classes - end - end - return data -end -function otf.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) - if okay then - return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) - else - return {} - end -end -local function copytotfm(data,cache_id) - if data then - local metadata=data.metadata - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local mathparameters={} - local resources=data.resources - local unicodes=resources.unicodes - local spaceunits=500 - local spacer="space" - local designsize=metadata.designsize or 100 - local minsize=metadata.minsize or designsize - local maxsize=metadata.maxsize or designsize - local mathspecs=metadata.math - if designsize==0 then - designsize=100 - minsize=100 - maxsize=100 - end - if mathspecs then - for name,value in next,mathspecs do - mathparameters[name]=value - end - end - for unicode in next,data.descriptions do - characters[unicode]={} - end - if mathspecs then - for unicode,character in next,characters do - local d=descriptions[unicode] - local m=d.math - if m then - local italic=m.italic - local vitalic=m.vitalic - local variants=m.hvariants - local parts=m.hparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.horiz_variants=parts - elseif parts then - character.horiz_variants=parts - italic=m.hitalic - end - local variants=m.vvariants - local parts=m.vparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.vert_variants=parts - elseif parts then - character.vert_variants=parts - end - if italic and italic~=0 then - character.italic=italic - end - if vitalic and vitalic~=0 then - character.vert_italic=vitalic - end - local accent=m.accent - if accent then - character.accent=accent - end - local kerns=m.kerns - if kerns then - character.mathkerns=kerns - end - end - end - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname - local fullname=metadata.fullname or fontname - local psname=fontname or fullname - local subfont=metadata.subfontindex - local units=metadata.units or 1000 - if units==0 then - units=1000 - metadata.units=1000 - report_otf("changing %a units to %a",0,units) - end - local monospaced=metadata.monospaced - local charwidth=metadata.averagewidth - local charxheight=metadata.xheight - local italicangle=metadata.italicangle - local hasitalics=metadata.hasitalics - properties.monospaced=monospaced - properties.hasitalics=hasitalics - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - local space=0x0020 - local emdash=0x2014 - if monospaced then - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width,"emdash" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - else - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - end - spaceunits=tonumber(spaceunits) or units/2 - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=1*units/2 - parameters.space_shrink=1*units/3 - parameters.x_height=2*units/5 - parameters.quad=units - if spaceunits<2*units/5 then - end - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight - else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end - end - parameters.designsize=(designsize/10)*65536 - parameters.minsize=(minsize/10)*65536 - parameters.maxsize=(maxsize/10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=units - parameters.vheight=metadata.defaultvheight - properties.space=spacer - properties.encodingbytes=2 - properties.format=data.format or formats.otf - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=psname - properties.name=filename or fullname - properties.subfont=subfont - properties.private=properties.private or data.private or privateoffset - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - mathparameters=mathparameters, - resources=resources, - properties=properties, - goodies=goodies, - } - end -end -local converters={ - woff={ - cachename="webfonts", - action=otf.readers.woff2otf, - } -} -local function checkconversion(specification) - local filename=specification.filename - local converter=converters[lower(file.suffix(filename))] - if converter then - local base=file.basename(filename) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if size>0 then - local cleanname=containers.cleanname(name) - local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) - if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then - report_otf("caching font %a in %a",filename,cachename) - converter.action(filename,cachename) - lfs.touch(cachename,time,time) - end - specification.filename=cachename - end - end -end -local function otftotfm(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - checkconversion(specification) - local name=specification.name - local sub=specification.sub - local subindex=specification.subindex - local filename=specification.filename - local features=specification.features.normal - local instance=specification.instance or (features and features.axis) - local rawdata=otf.load(filename,sub,instance) - if rawdata and next(rawdata) then - local descriptions=rawdata.descriptions - rawdata.lookuphash={} - tfmdata=copytotfm(rawdata,cache_id) - if tfmdata and next(tfmdata) then - local features=constructors.checkedfeatures("otf",features) - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=otf.setfeatures(tfmdata,features) - end - end - containers.write(constructors.cache,cache_id,tfmdata) - end - return tfmdata -end -local function read_from_otf(specification) - local tfmdata=otftotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata.properties.sub=specification.sub - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) - constructors.setname(tfmdata,specification) - fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) - end - return tfmdata -end -local function checkmathsize(tfmdata,mathsize) - local mathdata=tfmdata.shared.rawdata.metadata.math - local mathsize=tonumber(mathsize) - if mathdata then - local parameters=tfmdata.parameters - parameters.scriptpercentage=mathdata.ScriptPercentScaleDown - parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown - parameters.mathsize=mathsize - end -end -registerotffeature { - name="mathsize", - description="apply mathsize specified in the font", - initializers={ - base=checkmathsize, - node=checkmathsize, - } -} -function otf.collectlookups(rawdata,kind,script,language) - if not kind then - return - end - if not script then - script=default - end - if not language then - language=default - end - local lookupcache=rawdata.lookupcache - if not lookupcache then - lookupcache={} - rawdata.lookupcache=lookupcache - end - local kindlookup=lookupcache[kind] - if not kindlookup then - kindlookup={} - lookupcache[kind]=kindlookup - end - local scriptlookup=kindlookup[script] - if not scriptlookup then - scriptlookup={} - kindlookup[script]=scriptlookup - end - local languagelookup=scriptlookup[language] - if not languagelookup then - local sequences=rawdata.resources.sequences - local featuremap={} - local featurelist={} - if sequences then - for s=1,#sequences do - local sequence=sequences[s] - local features=sequence.features - if features then - features=features[kind] - if features then - features=features[script] or features[wildcard] - if features then - features=features[language] or features[wildcard] - if features then - if not featuremap[sequence] then - featuremap[sequence]=true - featurelist[#featurelist+1]=sequence - end - end - end - end - end - end - if #featurelist==0 then - featuremap,featurelist=false,false - end - else - featuremap,featurelist=false,false - end - languagelookup={ featuremap,featurelist } - scriptlookup[language]=languagelookup - end - return unpack(languagelookup) -end -local function getgsub(tfmdata,k,kind,value) - local shared=tfmdata.shared - local rawdata=shared and shared.rawdata - if rawdata then - local sequences=rawdata.resources.sequences - if sequences then - local properties=tfmdata.properties - local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) - if validlookups then - for i=1,#lookuplist do - local lookup=lookuplist[i] - local steps=lookup.steps - local nofsteps=lookup.nofsteps - for i=1,nofsteps do - local coverage=steps[i].coverage - if coverage then - local found=coverage[k] - if found then - return found,lookup.type - end - end - end - end - end - end - end -end -otf.getgsub=getgsub -function otf.getsubstitution(tfmdata,k,kind,value) - local found,kind=getgsub(tfmdata,k,kind,value) - if not found then - elseif kind=="gsub_single" then - return found - elseif kind=="gsub_alternate" then - local choice=tonumber(value) or 1 - return found[choice] or found[1] or k - end - return k -end -otf.getalternate=otf.getsubstitution -function otf.getmultiple(tfmdata,k,kind) - local found,kind=getgsub(tfmdata,k,kind) - if found and kind=="gsub_multiple" then - return found - end - return { k } -end -function otf.getkern(tfmdata,left,right,kind) - local kerns=getgsub(tfmdata,left,kind or "kern",true) - if kerns then - local found=kerns[right] - local kind=type(found) - if kind=="table" then - found=found[1][3] - elseif kind~="number" then - found=false - end - if found then - return found*tfmdata.parameters.factor - end - end - return 0 -end -local function check_otf(forced,specification,suffix) - local name=specification.name - if forced then - name=specification.forcedname - end - local fullname=findbinfile(name,suffix) or "" - if fullname=="" then - fullname=fonts.names.getfilename(name,suffix) or "" - end - if fullname~="" and not fonts.names.ignoredfile(fullname) then - specification.filename=fullname - return read_from_otf(specification) - end -end -local function opentypereader(specification,suffix) - local forced=specification.forced or "" - if formats[forced] then - return check_otf(true,specification,forced) - else - return check_otf(false,specification,suffix) - end -end -readers.opentype=opentypereader -function readers.otf(specification) return opentypereader(specification,"otf") end -function readers.ttf(specification) return opentypereader(specification,"ttf") end -function readers.ttc(specification) return opentypereader(specification,"ttf") end -function readers.woff(specification) - checkconversion(specification) - opentypereader(specification,"") -end -function otf.scriptandlanguage(tfmdata,attr) - local properties=tfmdata.properties - return properties.script or "dflt",properties.language or "dflt" -end -local function justset(coverage,unicode,replacement) - coverage[unicode]=replacement -end -otf.coverup={ - stepkey="steps", - actions={ - chainsubstitution=justset, - chainposition=justset, - substitution=justset, - alternate=justset, - multiple=justset, - kern=justset, - pair=justset, - single=justset, - ligature=function(coverage,unicode,ligature) - local first=ligature[1] - local tree=coverage[first] - if not tree then - tree={} - coverage[first]=tree - end - for i=2,#ligature do - local l=ligature[i] - local t=tree[l] - if not t then - t={} - tree[l]=t - end - tree=t - end - tree.ligature=unicode - end, - }, - register=function(coverage,featuretype,format) - return { - format=format, - coverage=coverage, - } - end -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] --- - -if not modules then modules={} end modules ['font-oto']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local concat,unpack=table.concat,table.unpack -local insert,remove=table.insert,table.remove -local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip -local type,next,tonumber,tostring=type,next,tonumber,tostring -local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) -local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) -local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) -local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) -local report_prepare=logs.reporter("fonts","otf prepare") -local fonts=fonts -local otf=fonts.handlers.otf -local otffeatures=otf.features -local registerotffeature=otffeatures.register -otf.defaultbasealternate="none" -local getprivate=fonts.constructors.getprivate -local wildcard="*" -local default="dflt" -local formatters=string.formatters -local f_unicode=formatters["%U"] -local f_uniname=formatters["%U (%s)"] -local f_unilist=formatters["% t (% t)"] -local function gref(descriptions,n) - if type(n)=="number" then - local name=descriptions[n].name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local num={} - local nam={} - local j=0 - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - j=j+1 - local di=descriptions[ni] - num[j]=f_unicode(ni) - nam[j]=di and di.name or "-" - end - end - return f_unilist(num,nam) - else - return "" - end -end -local function cref(feature,sequence) - return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) -end -local function report_substitution(feature,sequence,descriptions,unicode,substitution) - if unicode==substitution then - report_prepare("%s: base substitution %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base substitution %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,substitution)) - end -end -local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment) - if unicode==replacement then - report_prepare("%s: base alternate %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base alternate %s => %s (%S => %S)", - cref(feature,sequence), - gref(descriptions,unicode), - replacement and gref(descriptions,replacement), - value, - comment) - end -end -local function report_ligature(feature,sequence,descriptions,unicode,ligature) - report_prepare("%s: base ligature %s => %S", - cref(feature,sequence), - gref(descriptions,ligature), - gref(descriptions,unicode)) -end -local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value) - report_prepare("%s: base kern %s + %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,otherunicode), - value) -end -local basehash,basehashes,applied={},1,{} -local function registerbasehash(tfmdata) - local properties=tfmdata.properties - local hash=concat(applied," ") - local base=basehash[hash] - if not base then - basehashes=basehashes+1 - base=basehashes - basehash[hash]=base - end - properties.basehash=base - properties.fullname=(properties.fullname or properties.name).."-"..base - applied={} -end -local function registerbasefeature(feature,value) - applied[#applied+1]=feature.."="..tostring(value) -end -local function makefake(tfmdata,name,present) - local private=getprivate(tfmdata) - local character={ intermediate=true,ligatures={} } - resources.unicodes[name]=private - tfmdata.characters[private]=character - tfmdata.descriptions[private]={ name=name } - present[name]=private - return character -end -local function make_1(present,tree,name) - for k,v in next,tree do - if k=="ligature" then - present[name]=v - else - make_1(present,v,name.."_"..k) - end - end -end -local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done) - for k,v in next,tree do - if k=="ligature" then - local character=characters[preceding] - if not character then - if trace_baseinit then - report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) - end - character=makefake(tfmdata,name,present) - end - local ligatures=character.ligatures - if ligatures then - ligatures[unicode]={ char=v } - else - character.ligatures={ [unicode]={ char=v } } - end - if done then - local d=done[name] - if not d then - done[name]={ "dummy",v } - else - d[#d+1]=v - end - end - else - local code=present[name] or unicode - local name=name.."_"..k - make_2(present,tfmdata,characters,v,name,code,k,done) - end - end -end -local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local changed=tfmdata.changed - local ligatures={} - local alternate=tonumber(value) or true and 1 - local defaultalt=otf.defaultbasealternate - local trace_singles=trace_baseinit and trace_singles - local trace_alternatives=trace_baseinit and trace_alternatives - local trace_ligatures=trace_baseinit and trace_ligatures - if not changed then - changed={} - tfmdata.changed=changed - end - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - if kind=="gsub_single" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - if unicode~=data then - changed[unicode]=data - end - if trace_singles then - report_substitution(feature,sequence,descriptions,unicode,data) - end - end - end - elseif kind=="gsub_alternate" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - local replacement=data[alternate] - if replacement then - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") - end - elseif defaultalt=="first" then - replacement=data[1] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - elseif defaultalt=="last" then - replacement=data[#data] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - else - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") - end - end - end - end - elseif kind=="gsub_ligature" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - ligatures[#ligatures+1]={ unicode,data,"" } - if trace_ligatures then - report_ligature(feature,sequence,descriptions,unicode,data) - end - end - end - end - end - local nofligatures=#ligatures - if nofligatures>0 then - local characters=tfmdata.characters - local present={} - local done=trace_baseinit and trace_ligatures and {} - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode=ligature[1] - local tree=ligature[2] - make_1(present,tree,"ctx_"..unicode) - end - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode=ligature[1] - local tree=ligature[2] - local lookupname=ligature[3] - make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) - end - end -end -local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local properties=tfmdata.properties - local traceindeed=trace_baseinit and trace_kerns - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - local format=sequence.format - if kind=="gpos_pair" then - for i=1,#steps do - local step=steps[i] - local format=step.format - if format=="kern" or format=="move" then - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - if not kerns then - kerns={} - character.kerns=kerns - end - if traceindeed then - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - else - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - end - end - end - end - else - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - for otherunicode,kern in next,data do - local other=kern[2] - if other==true or (not other and not (kerns and kerns[otherunicode])) then - local kern=kern[1] - if kern==true then - elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then - else - kern=kern[3] - if kern~=0 then - if kerns then - kerns[otherunicode]=kern - else - kerns={ [otherunicode]=kern } - character.kerns=kerns - end - if traceindeed then - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - end - end - end - end - end - end - end - end -end -local function initializehashes(tfmdata) -end -local function checkmathreplacements(tfmdata,fullname,fixitalics) - if tfmdata.mathparameters then - local characters=tfmdata.characters - local changed=tfmdata.changed - if next(changed) then - if trace_preparing or trace_baseinit then - report_prepare("checking math replacements for %a",fullname) - end - for unicode,replacement in next,changed do - local u=characters[unicode] - local r=characters[replacement] - if u and r then - local n=u.next - local v=u.vert_variants - local h=u.horiz_variants - if fixitalics then - local ui=u.italic - if ui and not r.italic then - if trace_preparing then - report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) - end - r.italic=ui - end - end - if n and not r.next then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) - end - r.next=n - end - if v and not r.vert_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) - end - r.vert_variants=v - end - if h and not r.horiz_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) - end - r.horiz_variants=h - end - else - if trace_preparing then - report_prepare("error replacing %C by %U",unicode,replacement) - end - end - end - end - end -end -local function featuresinitializer(tfmdata,value) - if true then - local starttime=trace_preparing and os.clock() - local features=tfmdata.shared.features - local fullname=tfmdata.properties.fullname or "?" - if features then - initializehashes(tfmdata) - local collectlookups=otf.collectlookups - local rawdata=tfmdata.shared.rawdata - local properties=tfmdata.properties - local script=properties.script - local language=properties.language - local rawresources=rawdata.resources - local rawfeatures=rawresources and rawresources.features - local basesubstitutions=rawfeatures and rawfeatures.gsub - local basepositionings=rawfeatures and rawfeatures.gpos - local substitutionsdone=false - local positioningsdone=false - if basesubstitutions or basepositionings then - local sequences=tfmdata.resources.sequences - for s=1,#sequences do - local sequence=sequences[s] - local sfeatures=sequence.features - if sfeatures then - local order=sequence.order - if order then - for i=1,#order do - local feature=order[i] - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if not validlookups then - elseif basesubstitutions and basesubstitutions[feature] then - if trace_preparing then - report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) - end - preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - substitutionsdone=true - elseif basepositionings and basepositionings[feature] then - if trace_preparing then - report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) - end - preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - positioningsdone=true - end - end - end - end - end - end - end - if substitutionsdone then - checkmathreplacements(tfmdata,fullname,features.fixitalics) - end - registerbasehash(tfmdata) - end - if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) - end - end -end -registerotffeature { - name="features", - description="features", - default=true, - initializers={ - base=featuresinitializer, - } -} -otf.basemodeinitializer=featuresinitializer - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj” a37a1007b8a92c9e7d24064180c2a772] --- - -if not modules then modules={} end modules ['font-otj']={ - version=1.001, - optimize=true, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -if not nodes.properties then return end -local next,rawget,tonumber=next,rawget,tonumber -local fastcopy=table.fastcopy -local registertracker=trackers.register -local registerdirective=directives.register -local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) -local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) -local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) -local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) -local report_injections=logs.reporter("fonts","injections") -local report_spaces=logs.reporter("fonts","spaces") -local attributes,nodes,node=attributes,nodes,node -fonts=fonts -local hashes=fonts.hashes -local fontdata=hashes.identifiers -local fontmarks=hashes.marks -nodes.injections=nodes.injections or {} -local injections=nodes.injections -local tracers=nodes.tracers -local setcolor=tracers and tracers.colors.set -local resetcolor=tracers and tracers.colors.reset -local nodecodes=nodes.nodecodes -local glyph_code=nodecodes.glyph -local disc_code=nodecodes.disc -local kern_code=nodecodes.kern -local glue_code=nodecodes.glue -local nuts=nodes.nuts -local nodepool=nuts.pool -local tonode=nuts.tonode -local tonut=nuts.tonut -local setfield=nuts.setfield -local getnext=nuts.getnext -local getprev=nuts.getprev -local getid=nuts.getid -local getfont=nuts.getfont -local getchar=nuts.getchar -local getoffsets=nuts.getoffsets -local getboth=nuts.getboth -local getdisc=nuts.getdisc -local setdisc=nuts.setdisc -local setoffsets=nuts.setoffsets -local ischar=nuts.ischar -local getkern=nuts.getkern -local setkern=nuts.setkern -local setlink=nuts.setlink -local setwidth=nuts.setwidth -local getwidth=nuts.getwidth -local nextchar=nuts.traversers.char -local nextglue=nuts.traversers.glue -local insert_node_before=nuts.insert_before -local insert_node_after=nuts.insert_after -local properties=nodes.properties.data -local fontkern=nuts.pool and nuts.pool.fontkern -local italickern=nuts.pool and nuts.pool.italickern -local useitalickerns=false -directives.register("fonts.injections.useitalics",function(v) - if v then - report_injections("using italics for space kerns (tracing only)") - end - useitalickerns=v -end) -if not fontkern then - local thekern=nuts.new("kern",0) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - fontkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end -if not italickern then - local thekern=nuts.new("kern",3) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - italickern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end -function injections.installnewkern() end -local nofregisteredkerns=0 -local nofregisteredpositions=0 -local nofregisteredmarks=0 -local nofregisteredcursives=0 -local keepregisteredcounts=false -function injections.keepcounts() - keepregisteredcounts=true -end -function injections.resetcounts() - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - keepregisteredcounts=false -end -function injections.reset(n) - local p=rawget(properties,n) - if p then - p.injections=false - else - properties[n]=false - end -end -function injections.copy(target,source) - local sp=rawget(properties,source) - if sp then - local tp=rawget(properties,target) - local si=sp.injections - if si then - si=fastcopy(si) - if tp then - tp.injections=si - else - properties[target]={ - injections=si, - } - end - elseif tp then - tp.injections=false - else - properties[target]={ injections={} } - end - else - local tp=rawget(properties,target) - if tp then - tp.injections=false - else - properties[target]=false - end - end -end -function injections.setligaindex(n,index) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - i.ligaindex=index - else - p.injections={ - ligaindex=index - } - end - else - properties[n]={ - injections={ - ligaindex=index - } - } - end -end -function injections.getligaindex(n,default) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - return i.ligaindex or default - end - end - return default -end -function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag) - local dx=factor*(exit[1]-entry[1]) - local dy=-factor*(exit[2]-entry[2]) - local ws=tfmstart.width - local wn=tfmnext.width - nofregisteredcursives=nofregisteredcursives+1 - if rlmode<0 then - dx=-(dx+wn) - else - dx=dx-ws - end - if dx==0 then - dx=0 - end - local p=rawget(properties,start) - if p then - local i=p.injections - if i then - i.cursiveanchor=true - else - p.injections={ - cursiveanchor=true, - } - end - else - properties[start]={ - injections={ - cursiveanchor=true, - }, - } - end - local p=rawget(properties,nxt) - if p then - local i=p.injections - if i then - i.cursivex=dx - i.cursivey=dy - else - p.injections={ - cursivex=dx, - cursivey=dy, - } - end - else - properties[nxt]={ - injections={ - cursivex=dx, - cursivey=dy, - }, - } - end - return dx,dy,nofregisteredcursives -end -function injections.setposition(kind,current,factor,rlmode,spec,injection) - local x=factor*(spec[1] or 0) - local y=factor*(spec[2] or 0) - local w=factor*(spec[3] or 0) - local h=factor*(spec[4] or 0) - if x~=0 or w~=0 or y~=0 or h~=0 then - local yoffset=y-h - local leftkern=x - local rightkern=w-x - if leftkern~=0 or rightkern~=0 or yoffset~=0 then - nofregisteredpositions=nofregisteredpositions+1 - if rlmode and rlmode<0 then - leftkern,rightkern=rightkern,leftkern - end - if not injection then - injection="injections" - end - local p=rawget(properties,current) - if p then - local i=p[injection] - if i then - if leftkern~=0 then - i.leftkern=(i.leftkern or 0)+leftkern - end - if rightkern~=0 then - i.rightkern=(i.rightkern or 0)+rightkern - end - if yoffset~=0 then - i.yoffset=(i.yoffset or 0)+yoffset - end - elseif leftkern~=0 or rightkern~=0 then - p[injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - } - else - p[injection]={ - yoffset=yoffset, - } - end - elseif leftkern~=0 or rightkern~=0 then - properties[current]={ - [injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - }, - } - else - properties[current]={ - [injection]={ - yoffset=yoffset, - }, - } - end - return x,y,w,h,nofregisteredpositions - end - end - return x,y,w,h -end -function injections.setkern(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - return dx,nofregisteredkerns - else - return 0,0 - end -end -function injections.setmove(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if rlmode and rlmode<0 then - if p then - local i=p[injection] - if i then - i.rightkern=dx+(i.rightkern or 0) - else - p[injection]={ - rightkern=dx, - } - end - else - properties[current]={ - [injection]={ - rightkern=dx, - }, - } - end - else - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - end - return dx,nofregisteredkerns - else - return 0,0 - end -end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) - local dx=factor*(ba[1]-ma[1]) - local dy=factor*(ba[2]-ma[2]) - nofregisteredmarks=nofregisteredmarks+1 - if rlmode>=0 then - dx=tfmbase.width-dx - end - local p=rawget(properties,start) - if p then - local i=p.injections - if i then - if i.markmark then - else - i.markx=dx - i.marky=dy - i.markdir=rlmode or 0 - i.markbase=nofregisteredmarks - i.markbasenode=base - i.markmark=mkmk - i.checkmark=checkmark - end - else - p.injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - } - end - else - properties[start]={ - injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - }, - } - end - return dx,dy,nofregisteredmarks -end -local function dir(n) - return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" -end -local function showchar(n,nested) - local char=getchar(n) - report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) -end -local function show(n,what,nested,symbol) - if n then - local p=rawget(properties,n) - if p then - local i=p[what] - if i then - local leftkern=i.leftkern or 0 - local rightkern=i.rightkern or 0 - local yoffset=i.yoffset or 0 - local markx=i.markx or 0 - local marky=i.marky or 0 - local markdir=i.markdir or 0 - local markbase=i.markbase or 0 - local cursivex=i.cursivex or 0 - local cursivey=i.cursivey or 0 - local ligaindex=i.ligaindex or 0 - local cursbase=i.cursiveanchor - local margin=nested and 4 or 2 - if rightkern~=0 or yoffset~=0 then - report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) - elseif leftkern~=0 then - report_injections("%w%s kern: dx %p",margin,symbol,leftkern) - end - if markx~=0 or marky~=0 or markbase~=0 then - report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") - end - if cursivex~=0 or cursivey~=0 then - if cursbase then - report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) - else - report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) - end - elseif cursbase then - report_injections("%w%s curs: base",margin,symbol) - end - if ligaindex~=0 then - report_injections("%w%s liga: index %i",margin,symbol,ligaindex) - end - end - end - end -end -local function showsub(n,what,where) - report_injections("begin subrun: %s",where) - for n in nextchar,n do - showchar(n,where) - show(n,what,where," ") - end - report_injections("end subrun") -end -local function trace(head,where) - report_injections() - report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", - where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) - local n=head - while n do - local id=getid(n) - if id==glyph_code then - showchar(n) - show(n,"injections",false," ") - show(n,"preinjections",false,"<") - show(n,"postinjections",false,">") - show(n,"replaceinjections",false,"=") - show(n,"emptyinjections",false,"*") - elseif id==disc_code then - local pre,post,replace=getdisc(n) - if pre then - showsub(pre,"preinjections","pre") - end - if post then - showsub(post,"postinjections","post") - end - if replace then - showsub(replace,"replaceinjections","replace") - end - show(n,"emptyinjections",false,"*") - end - n=getnext(n) - end - report_injections("end run") -end -local function show_result(head) - local current=head - local skipping=false - while current do - local id=getid(current) - if id==glyph_code then - local w=getwidth(current) - local x,y=getoffsets(current) - report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) - skipping=false - elseif id==kern_code then - report_injections("kern: %p",getkern(current)) - skipping=false - elseif not skipping then - report_injections() - skipping=true - end - current=getnext(current) - end - report_injections() -end -local function inject_kerns_only(head,where) - if trace_injections then - trace(head,"kerns") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - if prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - prevdisc=nil - elseif char==false then - prevdisc=nil - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevdisc=current - else - prevdisc=nil - end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredkerns=0 - end - if trace_injections then - show_result(head) - end - return head -end -local function inject_positions_only(head,where) - if trace_injections then - trace(head,"positions") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - elseif prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - if next and getid(next)==glue_code then - if useitalickerns then - insert_node_after(head,current,italickern(rightkern)) - else - setwidth(next,getwidth(next)+rightkern) - end - else - insert_node_after(head,current,fontkern(rightkern)) - end - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - replace=fontkern(rightkern) - done=true - end - end - end - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end - end - if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil - end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredpositions=0 - end - if trace_injections then - show_result(head) - end - return head -end -local function showoffset(n,flag) - local x,y=getoffsets(n) - if x~=0 or y~=0 then - setcolor(n,"darkgray") - end -end -local function inject_everything(head,where) - if trace_injections then - trace(head,"everything") - end - local hascursives=nofregisteredcursives>0 - local hasmarks=nofregisteredmarks>0 - local current=head - local last=nil - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - local cursiveanchor=nil - local minc=0 - local maxc=0 - local glyphs={} - local marks={} - local nofmarks=0 - local function processmark(p,n,pn) - local px,py=getoffsets(p) - local nx,ny=getoffsets(n) - local ox=0 - local rightkern=nil - local pp=rawget(properties,p) - if pp then - pp=pp.injections - if pp then - rightkern=pp.rightkern - end - end - local markdir=pn.markdir - if rightkern then - ox=px-(pn.markx or 0)-rightkern - if markdir and markdir<0 then - if not pn.markmark then - ox=ox+(pn.leftkern or 0) - end - else - if false then - local leftkern=pp.leftkern - if leftkern then - ox=ox-leftkern - end - end - end - else - ox=px-(pn.markx or 0) - if markdir and markdir<0 then - if not pn.markmark then - local leftkern=pn.leftkern - if leftkern then - ox=ox+leftkern - end - end - end - if pn.checkmark then - local wn=getwidth(n) - if wn and wn~=0 then - wn=wn/2 - if trace_injections then - report_injections("correcting non zero width mark %C",getchar(n)) - end - insert_node_before(n,n,fontkern(-wn)) - insert_node_after(n,n,fontkern(-wn)) - end - end - end - local oy=ny+py+(pn.marky or 0) - if not pn.markmark then - local yoffset=pn.yoffset - if yoffset then - oy=oy+yoffset - end - end - setoffsets(n,ox,oy) - if trace_marks then - showoffset(n,true) - end - end - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local pm=i.markbasenode - if pm then - nofmarks=nofmarks+1 - marks[nofmarks]=current - else - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - if hascursives then - local cursivex=i.cursivex - if cursivex then - if cursiveanchor then - if cursivex~=0 then - i.leftkern=(i.leftkern or 0)+cursivex - end - if maxc==0 then - minc=1 - maxc=1 - glyphs[1]=cursiveanchor - else - maxc=maxc+1 - glyphs[maxc]=cursiveanchor - end - properties[cursiveanchor].cursivedy=i.cursivey - last=current - else - maxc=0 - end - elseif maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - cursiveanchor=nil - end - if i.cursiveanchor then - cursiveanchor=current - else - if maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - end - cursiveanchor=nil - end - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - elseif prev and getid(prev)==glue_code then - if useitalickerns then - head=insert_node_before(head,current,italickern(leftkern)) - else - setwidth(prev,getwidth(prev)+leftkern) - end - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - if next and getid(next)==glue_code then - if useitalickerns then - insert_node_after(head,current,italickern(rightkern)) - else - setwidth(next,getwidth(next)+rightkern) - end - else - insert_node_after(head,current,fontkern(rightkern)) - end - end - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - replace=fontkern(rightkern) - done=true - end - end - end - end - end - if prevdisc then - if p then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=fontkern(leftkern) - done=true - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - else - if hascursives and maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - local xi,yi=getoffsets(ti) - setoffsets(ti,xi,yi+ny) - end - maxc=0 - cursiveanchor=nil - end - end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in nextchar,pre do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if post then - for n in nextchar,post do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if replace then - for n in nextchar,replace do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end - end - if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end - end - end - if done then - setdisc(current,pre,post,replace) - end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil - end - prev=current - current=next - end - if hascursives and maxc>0 then - local nx,ny=getoffsets(last) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - end - if nofmarks>0 then - for i=1,nofmarks do - local m=marks[i] - local p=rawget(properties,m) - local i=p.injections - local b=i.markbasenode - processmark(b,m,i) - end - elseif hasmarks then - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - end - if trace_injections then - show_result(head) - end - return head -end -local triggers=false -function nodes.injections.setspacekerns(font,sequence) - if triggers then - triggers[font]=sequence - else - triggers={ [font]=sequence } - end -end -local getthreshold -if context then - local threshold=1 - local parameters=fonts.hashes.parameters - directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) - getthreshold=function(font) - local p=parameters[font] - local f=p.factor - local s=p.spacing - local t=threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end -else - injections.threshold=0 - getthreshold=function(font) - local p=fontdata[font].parameters - local f=p.factor - local s=p.spacing - local t=injections.threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end -end -injections.getthreshold=getthreshold -function injections.isspace(n,threshold,id) - if (id or getid(n))==glue_code then - local w=getwidth(n) - if threshold and w>threshold then - return 32 - end - end -end -local getspaceboth=getboth -function injections.installgetspaceboth(gb) - getspaceboth=gb or getboth -end -local function injectspaces(head) - if not triggers then - return head - end - local lastfont=nil - local spacekerns=nil - local leftkerns=nil - local rightkerns=nil - local factor=0 - local threshold=0 - local leftkern=false - local rightkern=false - local function updatefont(font,trig) - leftkerns=trig.left - rightkerns=trig.right - lastfont=font - threshold, - factor=getthreshold(font) - end - for n in nextglue,head do - local prev,next=getspaceboth(n) - local prevchar=prev and ischar(prev) - local nextchar=next and ischar(next) - if nextchar then - local font=getfont(next) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if rightkerns then - rightkern=rightkerns[nextchar] - end - end - end - if prevchar then - local font=getfont(prev) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if leftkerns then - leftkern=leftkerns[prevchar] - end - end - end - if leftkern then - local old=getwidth(n) - if old>threshold then - if rightkern then - if useitalickerns then - local lnew=leftkern*factor - local rnew=rightkern*factor - if trace_spaces then - report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) - end - head=insert_node_before(head,n,italickern(lnew)) - insert_node_after(head,n,italickern(rnew)) - else - local new=old+(leftkern+rightkern)*factor - if trace_spaces then - report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) - end - setwidth(n,new) - end - rightkern=false - else - if useitalickerns then - local new=leftkern*factor - if trace_spaces then - report_spaces("%C [%p + %p]",prevchar,old,new) - end - insert_node_after(head,n,italickern(new)) - else - local new=old+leftkern*factor - if trace_spaces then - report_spaces("%C [%p -> %p]",prevchar,old,new) - end - setwidth(n,new) - end - end - end - leftkern=false - elseif rightkern then - local old=getwidth(n) - if old>threshold then - if useitalickerns then - local new=rightkern*factor - if trace_spaces then - report_spaces("[%p + %p] %C",old,new,nextchar) - end - insert_node_after(head,n,italickern(new)) - else - local new=old+rightkern*factor - if trace_spaces then - report_spaces("[%p -> %p] %C",old,new,nextchar) - end - setwidth(n,new) - end - else - end - rightkern=false - end - end - triggers=false - return head -end -function injections.handler(head,where) - if triggers then - head=injectspaces(head) - end - if nofregisteredmarks>0 or nofregisteredcursives>0 then - if trace_injections then - report_injections("injection variant %a","everything") - end - return inject_everything(head,where) - elseif nofregisteredpositions>0 then - if trace_injections then - report_injections("injection variant %a","positions") - end - return inject_positions_only(head,where) - elseif nofregisteredkerns>0 then - if trace_injections then - report_injections("injection variant %a","kerns") - end - return inject_kerns_only(head,where) - else - return head - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota” f31232af3a694ae3d50380a5a92f88d3] --- - -if not modules then modules={} end modules ['font-ota']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local type=type -local setmetatableindex=table.setmetatableindex -if not trackers then trackers={ register=function() end } end -local fonts,nodes,node=fonts,nodes,node -local allocate=utilities.storage.allocate -local otf=fonts.handlers.otf -local analyzers=fonts.analyzers -local initializers=allocate() -local methods=allocate() -analyzers.initializers=initializers -analyzers.methods=methods -local nuts=nodes.nuts -local tonut=nuts.tonut -local getnext=nuts.getnext -local getprev=nuts.getprev -local getprev=nuts.getprev -local getprop=nuts.getprop -local setprop=nuts.setprop -local getsubtype=nuts.getsubtype -local getchar=nuts.getchar -local ischar=nuts.ischar -local end_of_math=nuts.end_of_math -local nodecodes=nodes.nodecodes -local disc_code=nodecodes.disc -local math_code=nodecodes.math -local fontdata=fonts.hashes.identifiers -local categories=characters and characters.categories or {} -local chardata=characters and characters.data -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local setstate=nuts.setstate -local getstate=nuts.getstate -if not setstate or not getstate then - setstate=function(n,v) - setprop(n,"state",v) - end - getstate=function(n,v) - local s=getprop(n,"state") - if v then - return s==v - else - return s - end - end - nuts.setstate=setstate - nuts.getstate=getstate -end -local s_init=1 local s_rphf=7 -local s_medi=2 local s_half=8 -local s_fina=3 local s_pref=9 -local s_isol=4 local s_blwf=10 -local s_mark=5 local s_pstf=11 -local s_rest=6 -local states=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - mark=s_mark, - rest=s_rest, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, -} -local features=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, -} -analyzers.states=states -analyzers.features=features -analyzers.useunicodemarks=false -function analyzers.setstate(head,font) - local useunicodemarks=analyzers.useunicodemarks - local tfmdata=fontdata[font] - local descriptions=tfmdata.descriptions - local first,last,current,n,done=nil,nil,head,0,false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - done=true - local d=descriptions[char] - if d then - if d.class=="mark" then - done=true - setstate(current,s_mark) - elseif useunicodemarks and categories[char]=="mn" then - done=true - setstate(current,s_mark) - elseif n==0 then - first,last,n=current,current,1 - setstate(current,s_init) - else - last,n=current,n+1 - setstate(current,s_medi) - end - else - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - end - elseif char==false then - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - elseif id==disc_code then - setstate(current,s_medi) - last=current - else - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if first and first==last then - setstate(last,s_isol) - elseif last then - setstate(last,s_fina) - end - return head,done -end -local function analyzeinitializer(tfmdata,value) - local script,language=otf.scriptandlanguage(tfmdata) - local action=initializers[script] - if not action then - elseif type(action)=="function" then - return action(tfmdata,value) - else - local action=action[language] - if action then - return action(tfmdata,value) - end - end -end -local function analyzeprocessor(head,font,attr) - local tfmdata=fontdata[font] - local script,language=otf.scriptandlanguage(tfmdata,attr) - local action=methods[script] - if not action then - elseif type(action)=="function" then - return action(head,font,attr) - else - action=action[language] - if action then - return action(head,font,attr) - end - end - return head,false -end -registerotffeature { - name="analyze", - description="analysis of character classes", - default=true, - initializers={ - node=analyzeinitializer, - }, - processors={ - position=1, - node=analyzeprocessor, - } -} -methods.latn=analyzers.setstate -local arab_warned={} -local function warning(current,what) - local char=getchar(current) - if not arab_warned[char] then - log.report("analyze","arab: character %C has no %a class",char,what) - arab_warned[char]=true - end -end -local mappers=allocate { - l=s_init, - d=s_medi, - c=s_medi, - r=s_fina, - u=s_isol, -} -local classifiers=characters.classifiers -if not classifiers then - local f_arabic,l_arabic=characters.blockrange("arabic") - local f_syriac,l_syriac=characters.blockrange("syriac") - local f_mandiac,l_mandiac=characters.blockrange("mandiac") - local f_nko,l_nko=characters.blockrange("nko") - local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") - classifiers=setmetatableindex(function(t,k) - if type(k)=="number" then - local c=chardata[k] - local v=false - if c then - local arabic=c.arabic - if arabic then - v=mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - v=false - end - elseif (k>=f_arabic and k<=l_arabic) or - (k>=f_syriac and k<=l_syriac) or - (k>=f_mandiac and k<=l_mandiac) or - (k>=f_nko and k<=l_nko) or - (k>=f_ext_a and k<=l_ext_a) then - if categories[k]=="mn" then - v=s_mark - else - v=s_rest - end - end - end - t[k]=v - return v - end - end) - characters.classifiers=classifiers -end -function methods.arab(head,font,attr) - local first,last,c_first,c_last - local current=head - local done=false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - done=true - local classifier=classifiers[char] - if not classifier then - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - elseif classifier==s_mark then - setstate(current,s_mark) - elseif classifier==s_isol then - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - setstate(current,s_isol) - elseif classifier==s_medi then - if first then - last=current - c_last=classifier - setstate(current,s_medi) - else - setstate(current,s_init) - first=current - c_first=classifier - end - elseif classifier==s_fina then - if last then - if getstate(last)~=s_init then - setstate(last,s_medi) - end - setstate(current,s_fina) - first,last=nil,nil - elseif first then - setstate(current,s_fina) - first=nil - else - setstate(current,s_isol) - end - else - setstate(current,s_rest) - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - end - else - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - first=nil - end - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if last then - if c_last==s_medi or c_last==s_fina then - setstate(last,s_fina) - else - warning(last,"fina") - setstate(last,s_error) - end - elseif first then - if c_first==s_medi or c_first==s_fina then - setstate(first,s_isol) - else - warning(first,"isol") - setstate(first,s_error) - end - end - return head,done -end -methods.syrc=methods.arab -methods.mand=methods.arab -methods.nko=methods.arab -do - local joining=setmetatableindex(function(t,k) - if type(k)=="number" then - local c=chardata[k] - local v=false - if c then - local mongolian=c.mongolian - v=mongolian - end - t[k]=v - return v - end - end) - function methods.mong(head,font,attr) - local first,last - local current=head - local done=false - local prevjoin=nil - local prestate=nil - current=tonut(current) - local function wrapup() - if last then - if last~=first then - local s=getstate(last) - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - end - last=nil - first=nil - prevjoin=nil - prestate=nil - end - end - while current do - local char,id=ischar(current,font) - if char and not getstate(current) then - local currjoin=joining[char] - done=true - if not last then - setstate(current,s_isol) - prevjoin=currjoin - first=current - last=current - prevstate=s_isol - elseif currjoin=="t" then - last=current - elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then - if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then - local s=getstate(last) - if s==s_isol then - setstate(last,s_init) - elseif s==s_fina then - setstate(last,s_medi) - end - setstate(current,s_fina) - prevstate=s_fina - elseif prevjoin=="nj" or prevjoin=="l" then - local s=getstate(last) - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - setstate(current,s_isol) - prevstate=s_isol - end - prevjoin=currjoin - last=current - elseif prevjoin=="nj" or prevjoin=="r" then - if s==s_medi then - setstate(last,s_fina) - elseif s==s_init then - setstate(last,s_isol) - end - setstate(current,s_isol) - prevjoin=currjoin - prevstate=s_isol - last=current - elseif last then - wrapup() - end - else - if last then - wrapup() - end - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if last then - wrapup() - end - return head,done - end -end -directives.register("otf.analyze.useunicodemarks",function(v) - analyzers.useunicodemarks=v -end) - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots” c507280651dcbc549f1d8a5622da8667] --- - -if not modules then modules={} end modules ['font-ots']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", -} -local type,next,tonumber=type,next,tonumber -local random=math.random -local formatters=string.formatters -local insert=table.insert -local registertracker=trackers.register -local logs=logs -local trackers=trackers -local nodes=nodes -local attributes=attributes -local fonts=fonts -local otf=fonts.handlers.otf -local tracers=nodes.tracers -local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) -local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) -local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) -local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) -local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) -local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) -local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) -local trace_details=false registertracker("otf.details",function(v) trace_details=v end) -local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) -local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) -local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) -local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) -local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) -local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) -local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) -local forcediscretionaries=false -local forcepairadvance=false -directives.register("otf.forcediscretionaries",function(v) - forcediscretionaries=v -end) -directives.register("otf.forcepairadvance",function(v) - forcepairadvance=v -end) -local report_direct=logs.reporter("fonts","otf direct") -local report_subchain=logs.reporter("fonts","otf subchain") -local report_chain=logs.reporter("fonts","otf chain") -local report_process=logs.reporter("fonts","otf process") -local report_warning=logs.reporter("fonts","otf warning") -local report_run=logs.reporter("fonts","otf run") -registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures") -registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive") -registertracker("otf.actions","otf.substitutions","otf.positions") -registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") -registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") -local nuts=nodes.nuts -local getnext=nuts.getnext -local setnext=nuts.setnext -local getprev=nuts.getprev -local setprev=nuts.setprev -local getboth=nuts.getboth -local setboth=nuts.setboth -local getid=nuts.getid -local getstate=nuts.getstate -local getsubtype=nuts.getsubtype -local setsubtype=nuts.setsubtype -local getchar=nuts.getchar -local setchar=nuts.setchar -local getdisc=nuts.getdisc -local setdisc=nuts.setdisc -local getreplace=nuts.getreplace -local setlink=nuts.setlink -local getwidth=nuts.getwidth -local getattr=nuts.getattr -local getglyphdata=nuts.getglyphdata -local copy_no_components=nuts.copy_no_components -local copy_only_glyphs=nuts.copy_only_glyphs -local count_components=nuts.count_components -local set_components=nuts.set_components -local get_components=nuts.get_components -local ischar=nuts.ischar -local usesfont=nuts.uses_font -local insert_node_after=nuts.insert_after -local copy_node=nuts.copy -local copy_node_list=nuts.copy_list -local remove_node=nuts.remove -local find_node_tail=nuts.tail -local flush_node_list=nuts.flush_list -local flush_node=nuts.flush_node -local end_of_math=nuts.end_of_math -local start_of_par=nuts.start_of_par -local setmetatable=setmetatable -local setmetatableindex=table.setmetatableindex -local nextnode=nuts.traversers.node -local nodecodes=nodes.nodecodes -local glyphcodes=nodes.glyphcodes -local disccodes=nodes.disccodes -local glyph_code=nodecodes.glyph -local glue_code=nodecodes.glue -local disc_code=nodecodes.disc -local math_code=nodecodes.math -local dir_code=nodecodes.dir -local localpar_code=nodecodes.localpar -local lefttoright_code=nodes.dirvalues.lefttoright -local righttoleft_code=nodes.dirvalues.righttoleft -local discretionarydisc_code=disccodes.discretionary -local ligatureglyph_code=glyphcodes.ligature -local a_noligature=attributes.private("noligature") -local injections=nodes.injections -local setmark=injections.setmark -local setcursive=injections.setcursive -local setkern=injections.setkern -local setmove=injections.setmove -local setposition=injections.setposition -local resetinjection=injections.reset -local copyinjection=injections.copy -local setligaindex=injections.setligaindex -local getligaindex=injections.getligaindex -local fontdata=fonts.hashes.identifiers -local fontfeatures=fonts.hashes.features -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local onetimemessage=fonts.loggers.onetimemessage or function() end -local getrandom=utilities and utilities.randomizer and utilities.randomizer.get -otf.defaultnodealternate="none" -local tfmdata=false -local characters=false -local descriptions=false -local marks=false -local classes=false -local currentfont=false -local factor=0 -local threshold=0 -local checkmarks=false -local discs=false -local spaces=false -local sweepnode=nil -local sweephead={} -local notmatchpre={} -local notmatchpost={} -local notmatchreplace={} -local handlers={} -local isspace=injections.isspace -local getthreshold=injections.getthreshold -local checkstep=(tracers and tracers.steppers.check) or function() end -local registerstep=(tracers and tracers.steppers.register) or function() end -local registermessage=(tracers and tracers.steppers.message) or function() end -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_direct(...) -end -local function logwarning(...) - report_direct(...) -end -local gref do - local f_unicode=formatters["U+%X"] - local f_uniname=formatters["U+%X (%s)"] - local f_unilist=formatters["% t"] - gref=function(n) - if type(n)=="number" then - local description=descriptions[n] - local name=description and description.name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local t={} - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - local di=descriptions[ni] - local nn=di and di.name - if nn then - t[#t+1]=f_uniname(ni,nn) - else - t[#t+1]=f_unicode(ni) - end - end - end - return f_unilist(t) - else - return "" - end - end -end -local function cref(dataset,sequence,index) - if not dataset then - return "no valid dataset" - end - local merged=sequence.merged and "merged " or "" - if index then - return formatters["feature %a, type %a, %schain lookup %a, index %a"]( - dataset[4],sequence.type,merged,sequence.name,index) - else - return formatters["feature %a, type %a, %schain lookup %a"]( - dataset[4],sequence.type,merged,sequence.name) - end -end -local function pref(dataset,sequence) - return formatters["feature %a, type %a, %slookup %a"]( - dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) -end -local function mref(rlmode) - if not rlmode or rlmode>=0 then - return "l2r" - else - return "r2l" - end -end -local function flattendisk(head,disc) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prev,next=getboth(disc) - local ishead=head==disc - setdisc(disc) - flush_node(disc) - if pre then - flush_node_list(pre) - end - if post then - flush_node_list(post) - end - if ishead then - if replace then - if next then - setlink(replacetail,next) - end - return replace,replace - elseif next then - return next,next - else - end - else - if replace then - if next then - setlink(replacetail,next) - end - setlink(prev,replace) - return head,replace - else - setlink(prev,next) - return head,next - end - end -end -local function appenddisc(disc,list) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local posthead=list - local replacehead=copy_node_list(list) - if post then - setlink(posttail,posthead) - else - post=posthead - end - if replace then - setlink(replacetail,replacehead) - else - replace=replacehead - end - setdisc(disc,pre,post,replace) -end -local function markstoligature(head,start,stop,char) - if start==stop and getchar(start)==char then - return head,start - else - local prev=getprev(start) - local next=getnext(stop) - setprev(start) - setnext(stop) - local base=copy_no_components(start,copyinjection) - if head==start then - head=base - end - resetinjection(base) - setchar(base,char) - setsubtype(base,ligatureglyph_code) - set_components(base,start) - setlink(prev,base,next) - return head,base - end -end -local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if getattr(start,a_noligature)==1 then - return head,start - end - if start==stop and getchar(start)==char then - resetinjection(start) - setchar(start,char) - return head,start - end - local prev=getprev(start) - local next=getnext(stop) - local comp=start - setprev(start) - setnext(stop) - local base=copy_no_components(start,copyinjection) - if start==head then - head=base - end - resetinjection(base) - setchar(base,char) - setsubtype(base,ligatureglyph_code) - set_components(base,comp) - setlink(prev,base,next) - if not discfound then - local deletemarks=not skiphash or hasmarks - local components=start - local baseindex=0 - local componentindex=0 - local head=base - local current=base - while start do - local char=getchar(start) - if not marks[char] then - baseindex=baseindex+componentindex - componentindex=count_components(start,marks) - elseif not deletemarks then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - local n=copy_node(start) - copyinjection(n,start) - head,current=insert_node_after(head,current,n) - elseif trace_marks then - logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char)) - end - start=getnext(start) - end - local start=getnext(current) - while start do - local char=ischar(start) - if char then - if marks[char] then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - start=getnext(start) - else - break - end - else - break - end - end - else - local discprev,discnext=getboth(discfound) - if discprev and discnext then - local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) - if not replace then - local prev=getprev(base) - local copied=copy_only_glyphs(comp) - if pre then - setlink(discprev,pre) - else - setnext(discprev) - end - pre=comp - if post then - setlink(posttail,discnext) - setprev(post) - else - post=discnext - setprev(discnext) - end - setlink(prev,discfound,next) - setboth(base) - set_components(base,copied) - replace=base - if forcediscretionaries then - setdisc(discfound,pre,post,replace,discretionarydisc_code) - else - setdisc(discfound,pre,post,replace) - end - base=prev - end - end - end - return head,base -end -local function multiple_glyphs(head,start,multiple,skiphash,what,stop) - local nofmultiples=#multiple - if nofmultiples>0 then - resetinjection(start) - setchar(start,multiple[1]) - if nofmultiples>1 then - local sn=getnext(start) - for k=2,nofmultiples do - local n=copy_node(start) - resetinjection(n) - setchar(n,multiple[k]) - insert_node_after(head,start,n) - start=n - end - if what==true then - elseif what>1 then - local m=multiple[nofmultiples] - for i=2,what do - local n=copy_node(start) - resetinjection(n) - setchar(n,m) - insert_node_after(head,start,n) - start=n - end - end - end - return head,start,true - else - if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) - end - return head,start,false - end -end -local function get_alternative_glyph(start,alternatives,value) - local n=#alternatives - if n==1 then - return alternatives[1],trace_alternatives and "1 (only one present)" - elseif value=="random" then - local r=getrandom and getrandom("glyph",1,n) or random(1,n) - return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) - elseif value=="first" then - return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) - elseif value=="last" then - return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) - end - value=value==true and 1 or tonumber(value) - if type(value)~="number" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - end - if value>n then - local defaultalt=otf.defaultnodealternate - if defaultalt=="first" then - return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - elseif defaultalt=="last" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) - else - return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") - end - elseif value==0 then - return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") - elseif value<1 then - return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) - else - return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) - end -end -function handlers.gsub_single(head,start,dataset,sequence,replacement) - if trace_singles then - logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true -end -function handlers.gsub_alternate(head,start,dataset,sequence,alternative) - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local choice,comment=get_alternative_glyph(start,alternative,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) - end - end - return head,start,true -end -function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash) - if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) - end - return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) -end -function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) - local current=getnext(start) - if not current then - return head,start,false,nil - end - local stop=nil - local startchar=getchar(start) - if skiphash and skiphash[startchar] then - while current do - local char=ischar(current,currentfont) - if char then - local lg=ligature[char] - if lg then - stop=current - ligature=lg - current=getnext(current) - else - break - end - else - break - end - end - if stop then - local lig=ligature.ligature - if lig then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=markstoligature(head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) - else - head,start=markstoligature(head,start,stop,lig) - end - return head,start,true,false - else - end - end - else - local discfound=false - local hasmarks=marks[startchar] - while current do - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - current=getnext(current) - else - local lg=ligature[char] - if lg then - if marks[char] then - hasmarks=true - end - stop=current - ligature=lg - current=getnext(current) - else - break - end - end - elseif char==false then - break - elseif id==disc_code then - discfound=current - break - else - break - end - end - if discfound then - local pre,post,replace=getdisc(discfound) - local match - if replace then - local char=ischar(replace,currentfont) - if char and ligature[char] then - match=true - end - end - if not match and pre then - local char=ischar(pre,currentfont) - if char and ligature[char] then - match=true - end - end - if not match and not pre or not replace then - local n=getnext(discfound) - local char=ischar(n,currentfont) - if char and ligature[char] then - match=true - end - end - if match then - local ishead=head==start - local prev=getprev(start) - if stop then - setnext(stop) - local copy=copy_node_list(start) - local tail=stop - local liat=find_node_tail(copy) - if pre then - setlink(liat,pre) - end - if replace then - setlink(tail,replace) - end - pre=copy - replace=start - else - setnext(start) - local copy=copy_node(start) - if pre then - setlink(copy,pre) - end - if replace then - setlink(start,replace) - end - pre=copy - replace=start - end - setdisc(discfound,pre,post,replace) - if prev then - setlink(prev,discfound) - else - setprev(discfound) - head=discfound - end - start=discfound - return head,start,true,true - end - end - local lig=ligature.ligature - if lig then - if stop then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) - else - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) - end - else - resetinjection(start) - setchar(start,lig) - if trace_ligatures then - logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) - end - end - return head,start,true,false - else - end - end - return head,start,false,false -end -function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) - end - end - return head,start,true -end -function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext=getnext(start) - if not snext then - return head,start,false - else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") - end - return head,start,true - else - break - end - end - else - break - end - end - return head,start,false - end -end -function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - elseif trace_bugs then - logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) - end - elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - else - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) - end - end - end - elseif trace_bugs then - onetimemessage(currentfont,basechar,"no base anchors",report_fonts) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) - end - return head,start,false -end -function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) - local startchar=getchar(start) - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - end - break - end - end - end - return head,start,false -end -local chainprocs={} -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_subchain(...) -end -local logwarning=report_subchain -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_chain(...) -end -local logwarning=report_chain -local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash) - local char=getchar(start) - local replacement=replacements[char] - if replacement then - if trace_singles then - logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true - else - return head,start,false - end -end -chainprocs.reversesub=reversesub -local function reportzerosteps(dataset,sequence) - logwarning("%s: no steps",cref(dataset,sequence)) -end -local function reportmoresteps(dataset,sequence) - logwarning("%s: more than 1 step",cref(dataset,sequence)) -end -local function getmapping(dataset,sequence,currentlookup) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps==0 then - reportzerosteps(dataset,sequence) - currentlookup.mapping=false - return false - else - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local mapping=steps[1].coverage - currentlookup.mapping=mapping - currentlookup.format=steps[1].format - return mapping - end -end -function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - if trace_chains then - logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) - end - head,start=remove_node(head,start,true) - return head,getprev(start),true -end -function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local replacement=mapping[currentchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) - end - else - if trace_singles then - logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) - end - resetinjection(current) - setchar(current,replacement) - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) - end - end - end - return head,start,false -end -function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local alternatives=mapping[currentchar] - if alternatives then - local choice,comment=get_alternative_glyph(current,alternatives,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) - end - end - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) - end - end - end - return head,start,false -end -function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local replacement=mapping[startchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) - end - else - if trace_multiples then - logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) - end - return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) - end - end - return head,start,false -end -function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local ligatures=mapping[startchar] - if not ligatures then - if trace_bugs then - logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) - end - else - local hasmarks=marks[startchar] - local current=getnext(start) - local discfound=false - local last=stop - local nofreplacements=1 - while current do - local id=getid(current) - if id==disc_code then - if not discfound then - discfound=current - end - if current==stop then - break - else - current=getnext(current) - end - else - local schar=getchar(current) - if skiphash and skiphash[schar] then - current=getnext(current) - else - local lg=ligatures[schar] - if lg then - ligatures=lg - last=current - nofreplacements=nofreplacements+1 - if marks[char] then - hasmarks=true - end - if current==stop then - break - else - current=getnext(current) - end - else - break - end - end - end - end - local ligature=ligatures.ligature - if ligature then - if chainindex then - stop=last - end - if trace_ligatures then - if start==stop then - logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) - else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) - end - end - head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) - return head,start,true,nofreplacements,discfound - elseif trace_bugs then - if start==stop then - logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) - else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) - end - end - end - end - return head,start,false,0,false -end -function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) - end - end - return head,start,true - end - end - return head,start,false -end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=currentlookup.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) - end - return head,start,true - else - break - end - end - end - end - end - end - return head,start,false -end -function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - end - end - end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) - end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) - end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) - end - end - return head,start,false -end -function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local exitanchors=mapping[startchar] - if exitanchors then - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - elseif trace_bugs then - onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) - end - break - end - end - end - elseif trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) - end - end - return head,start,false -end -local function show_skip(dataset,sequence,char,ck,class) - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) -end -local userkern=nuts.pool and nuts.pool.newkern -do if not userkern then - local thekern=nuts.new("kern",1) - local setkern=nuts.setkern - userkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end -end end -local function checked(head) - local current=head - while current do - if getid(current)==glue_code then - local kern=userkern(getwidth(current)) - if head==current then - local next=getnext(current) - if next then - setlink(kern,next) - end - flush_node(current) - head=kern - current=next - else - local prev,next=getboth(current) - setlink(prev,kern,next) - flush_node(current) - current=next - end - else - current=getnext(current) - end - end - return head -end -local function setdiscchecked(d,pre,post,replace) - if pre then pre=checked(pre) end - if post then post=checked(post) end - if replace then replace=checked(replace) end - setdisc(d,pre,post,replace) -end -local noflags={ false,false,false,false } -local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - local size=ck[5]-ck[4]+1 - local chainlookups=ck[6] - local done=false - if chainlookups then - if size==1 then - local chainlookup=chainlookups[1] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok - head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) - if ok then - done=true - end - else - logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) - end - end - else - local i=1 - local laststart=start - local nofchainlookups=#chainlookups - while start do - if skiphash then - while start do - local char=ischar(start,currentfont) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - break - end - else - break - end - end - end - local chainlookup=chainlookups[i] - if chainlookup then - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok,n - head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) - if ok then - done=true - if n and n>1 and i+n>nofchainlookups then - i=size - break - end - end - else - logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) - end - end - else - end - i=i+1 - if i>size or not start then - break - elseif start then - laststart=start - start=getnext(start) - end - end - if not start then - start=laststart - end - end - else - local replacements=ck[7] - if replacements then - head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) - else - done=true - if trace_contexts then - logprocess("%s: skipping match",cref(dataset,sequence)) - end - end - end - return head,start,done -end -local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) - if not start then - return head,start,false - end - local startishead=start==head - local seq=ck[3] - local f=ck[4] - local l=ck[5] - local s=#seq - local done=false - local sweepnode=sweepnode - local sweeptype=sweeptype - local sweepoverflow=false - local checkdisc=getprev(head) - local keepdisc=not sweepnode - local lookaheaddisc=nil - local backtrackdisc=nil - local current=start - local last=start - local prev=getprev(start) - local hasglue=false - local i=f - while i<=l do - local id=getid(current) - if id==glyph_code then - i=i+1 - last=current - current=getnext(current) - elseif id==glue_code then - i=i+1 - last=current - current=getnext(current) - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - lookaheaddisc=current - local replace=getreplace(current) - if not replace then - sweepoverflow=true - sweepnode=current - current=getnext(current) - else - while replace and i<=l do - if getid(replace)==glyph_code then - i=i+1 - end - replace=getnext(replace) - end - current=getnext(replace) - end - last=current - else - head,current=flattendisk(head,current) - end - else - last=current - current=getnext(current) - end - if current then - elseif sweepoverflow then - break - elseif sweeptype=="post" or sweeptype=="replace" then - current=getnext(sweepnode) - if current then - sweeptype=nil - sweepoverflow=true - else - break - end - else - break - end - end - if sweepoverflow then - local prev=current and getprev(current) - if not current or prev~=sweepnode then - local head=getnext(sweepnode) - local tail=nil - if prev then - tail=prev - setprev(current,sweepnode) - else - tail=find_node_tail(head) - end - setnext(sweepnode,current) - setprev(head) - setnext(tail) - appenddisc(sweepnode,head) - end - end - if l1 then - local current=prev - local i=f - local t=sweeptype=="pre" or sweeptype=="replace" - if not current and t and current==checkdisc then - current=getprev(sweepnode) - end - while current and i>1 do - local id=getid(current) - if id==glyph_code then - i=i-1 - elseif id==glue_code then - i=i-1 - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - if notmatchpost[current]~=notmatchreplace[current] then - backtrackdisc=current - end - local replace=getreplace(current) - while replace and i>1 do - if getid(replace)==glyph_code then - i=i-1 - end - replace=getnext(replace) - end - elseif notmatchpost[current]~=notmatchreplace[current] then - head,current=flattendisk(head,current) - end - end - current=getprev(current) - if t and current==checkdisc then - current=getprev(sweepnode) - end - end - end - local done=false - if lookaheaddisc then - local cf=start - local cl=getprev(lookaheaddisc) - local cprev=getprev(start) - local insertedmarks=0 - while cprev do - local char=ischar(cf,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cf=cprev - startishead=cf==head - cprev=getprev(cprev) - else - break - end - end - setlink(cprev,lookaheaddisc) - setprev(cf) - setnext(cl) - if startishead then - head=lookaheaddisc - end - local pre,post,replace=getdisc(lookaheaddisc) - local new=copy_node_list(cf) - local cnew=new - if pre then - setlink(find_node_tail(cf),pre) - end - if replace then - local tail=find_node_tail(new) - setlink(tail,replace) - end - for i=1,insertedmarks do - cnew=getnext(cnew) - end - cl=start - local clast=cnew - for i=f,l do - cl=getnext(cl) - clast=getnext(clast) - end - if not notmatchpre[lookaheaddisc] then - local ok=false - cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if not notmatchreplace[lookaheaddisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if hasglue then - setdiscchecked(lookaheaddisc,cf,post,new) - else - setdisc(lookaheaddisc,cf,post,new) - end - start=getprev(lookaheaddisc) - sweephead[cf]=getnext(clast) or false - sweephead[new]=getnext(cl) or false - elseif backtrackdisc then - local cf=getnext(backtrackdisc) - local cl=start - local cnext=getnext(start) - local insertedmarks=0 - while cnext do - local char=ischar(cnext,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cl=cnext - cnext=getnext(cnext) - else - break - end - end - setlink(backtrackdisc,cnext) - setprev(cf) - setnext(cl) - local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) - local new=copy_node_list(cf) - local cnew=find_node_tail(new) - for i=1,insertedmarks do - cnew=getprev(cnew) - end - local clast=cnew - for i=f,l do - clast=getnext(clast) - end - if not notmatchpost[backtrackdisc] then - local ok=false - cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if not notmatchreplace[backtrackdisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if post then - setlink(posttail,cf) - else - post=cf - end - if replace then - setlink(replacetail,new) - else - replace=new - end - if hasglue then - setdiscchecked(backtrackdisc,pre,post,replace) - else - setdisc(backtrackdisc,pre,post,replace) - end - start=getprev(backtrackdisc) - sweephead[post]=getnext(clast) or false - sweephead[replace]=getnext(last) or false - else - local ok=false - head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - return head,start,done -end -local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) - local rule=ck[1] - local lookuptype=ck[8] or ck[2] - local nofseq=#ck[3] - local first=ck[4] - local last=ck[5] - local char=getchar(start) - logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", - cref(dataset,sequence),rule,match and "matches" or "nomatch", - gref(char),first-1,last-first+1,nofseq-last,lookuptype, - discseen and "" or "no ",sweepnode and "" or "not ") -end -local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) - local sweepnode=sweepnode - local sweeptype=sweeptype - local postreplace - local prereplace - local checkdisc - local discseen - if sweeptype then - if sweeptype=="replace" then - postreplace=true - prereplace=true - else - postreplace=sweeptype=="post" - prereplace=sweeptype=="pre" - end - checkdisc=getprev(head) - end - local currentfont=currentfont - local skipped - local startprev, - startnext=getboth(start) - local done - local nofcontexts=contexts.n - local startchar=nofcontext==1 or ischar(start,currentfont) - for k=1,nofcontexts do - local ck=contexts[k] - local seq=ck[3] - local f=ck[4] - if not startchar or not seq[f][startchar] then - goto next - end - local s=seq.n - local l=ck[5] - local current=start - local last=start - if s==1 then - goto next - end - if l>f then - local discfound - local n=f+1 - last=startnext - while n<=l do - if postreplace and not last then - last=getnext(sweepnode) - sweeptype=nil - end - if last then - local char,id=ischar(last,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - last=getnext(last) - elseif seq[n][char] then - if nl then - break - end - pre=getnext(pre) - else - notmatchpre[last]=true - break - end - end - if n<=l then - notmatchpre[last]=true - end - else - notmatchpre[last]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>l then - break - end - replace=getnext(replace) - else - notmatchreplace[last]=true - if notmatchpre[last] then - goto next - else - break - end - end - end - if notmatchpre[last] then - goto next - end - end - last=getnext(last) - else - goto next - end - else - goto next - end - end - end - if f>1 then - if startprev then - local prev=startprev - if prereplace and prev==checkdisc then - prev=getprev(sweepnode) - end - if prev then - local discfound - local n=f-1 - while n>=1 do - if prev then - local char,id=ischar(prev,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - prev=getprev(prev) - elseif seq[n][char] then - if n>1 then - prev=getprev(prev) - end - n=n-1 - elseif discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - else - break - end - else - goto next - end - elseif char==false then - if discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - end - else - goto next - end - break - elseif id==disc_code then - discseen=true - discfound=prev - notmatchpre[prev]=true - notmatchpost[prev]=nil - notmatchreplace[prev]=nil - local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) - if pre~=start and post~=start and replace~=start then - if post then - local n=n - while posttail do - if seq[n][getchar(posttail)] then - n=n-1 - if posttail==post or n<1 then - break - else - posttail=getprev(posttail) - end - else - notmatchpost[prev]=true - break - end - end - if n>=1 then - notmatchpost[prev]=true - end - else - notmatchpost[prev]=true - end - if replace then - while replacetail do - if seq[n][getchar(replacetail)] then - n=n-1 - if replacetail==replace or n<1 then - break - else - replacetail=getprev(replacetail) - end - else - notmatchreplace[prev]=true - if notmatchpost[prev] then - goto next - else - break - end - end - end - else - end - end - prev=getprev(prev) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[prev]) or sn[0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - else - goto next - end - end - else - goto next - end - else - goto next - end - end - if s>l then - local current=last and getnext(last) - if not current and postreplace then - current=getnext(sweepnode) - end - if current then - local discfound - local n=l+1 - while n<=s do - if current then - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - current=getnext(current) - elseif seq[n][char] then - if ns then - break - else - pre=getnext(pre) - end - else - notmatchpre[current]=true - break - end - end - if n<=s then - notmatchpre[current]=true - end - else - notmatchpre[current]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>s then - break - else - replace=getnext(replace) - end - else - notmatchreplace[current]=true - if notmatchpre[current] then - goto next - else - break - end - end - end - else - end - current=getnext(current) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[current]) or sn[0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end - else - goto next - end - end - else - goto next - end - end - if trace_contexts then - chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) - end - if discseen or sweepnode then - head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) - else - head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) - end - if done then - break - end - ::next:: - end - if discseen then - notmatchpre={} - notmatchpost={} - notmatchreplace={} - end - return head,start,done -end -handlers.gsub_context=handle_contextchain -handlers.gsub_contextchain=handle_contextchain -handlers.gsub_reversecontextchain=handle_contextchain -handlers.gpos_contextchain=handle_contextchain -handlers.gpos_context=handle_contextchain -local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local l=steps[1].coverage[getchar(start)] - if l then - return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) - else - return head,start,false - end -end -chainprocs.gsub_context=chained_contextchain -chainprocs.gsub_contextchain=chained_contextchain -chainprocs.gsub_reversecontextchain=chained_contextchain -chainprocs.gpos_contextchain=chained_contextchain -chainprocs.gpos_context=chained_contextchain -local missing=setmetatableindex("table") -local logwarning=report_process -local resolved={} -local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end - end - report_process(...) -end -local sequencelists=setmetatableindex(function(t,font) - local sequences=fontdata[font].resources.sequences - if not sequences or not next(sequences) then - sequences=false - end - t[font]=sequences - return sequences -end) -do - local autofeatures=fonts.analyzers.features - local featuretypes=otf.tables.featuretypes - local defaultscript=otf.features.checkeddefaultscript - local defaultlanguage=otf.features.checkeddefaultlanguage - local wildcard="*" - local default="dflt" - local function initialize(sequence,script,language,enabled,autoscript,autolanguage) - local features=sequence.features - if features then - local order=sequence.order - if order then - local featuretype=featuretypes[sequence.type or "unknown"] - for i=1,#order do - local kind=order[i] - local valid=enabled[kind] - if valid then - local scripts=features[kind] - local languages=scripts and ( - scripts[script] or - scripts[wildcard] or - (autoscript and defaultscript(featuretype,autoscript,scripts)) - ) - local enabled=languages and ( - languages[language] or - languages[wildcard] or - (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) - ) - if enabled then - return { valid,autofeatures[kind] or false,sequence,kind } - end - end - end - else - end - end - return false - end - function otf.dataset(tfmdata,font) - local shared=tfmdata.shared - local properties=tfmdata.properties - local language=properties.language or "dflt" - local script=properties.script or "dflt" - local enabled=shared.features - local autoscript=enabled and enabled.autoscript - local autolanguage=enabled and enabled.autolanguage - local res=resolved[font] - if not res then - res={} - resolved[font]=res - end - local rs=res[script] - if not rs then - rs={} - res[script]=rs - end - local rl=rs[language] - if not rl then - rl={ - } - rs[language]=rl - local sequences=tfmdata.resources.sequences - if sequences then - for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1]=v - end - end - end - end - return rl - end -end -local function report_disc(what,n) - report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) -end -local function kernrun(disc,k_run,font,attr,...) - if trace_kernruns then - report_disc("kern",disc) - end - local prev,next=getboth(disc) - local nextstart=next - local done=false - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prevmarks=prev - while prevmarks do - local char=ischar(prevmarks,font) - if char and marks[char] then - prevmarks=getprev(prevmarks) - else - break - end - end - if prev and not ischar(prev,font) then - prev=false - end - if next and not ischar(next,font) then - next=false - end - if pre then - if k_run(pre,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,pre) - if k_run(prevmarks,"preinjections",pre,font,attr,...) then - done=true - end - setprev(pre) - setlink(prev,disc) - end - end - if post then - if k_run(post,"injections",nil,font,attr,...) then - done=true - end - if next then - setlink(posttail,next) - if k_run(posttail,"postinjections",next,font,attr,...) then - done=true - end - setnext(posttail) - setlink(disc,next) - end - end - if replace then - if k_run(replace,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,replace) - if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then - done=true - end - setprev(replace) - setlink(prev,disc) - end - if next then - setlink(replacetail,next) - if k_run(replacetail,"replaceinjections",next,font,attr,...) then - done=true - end - setnext(replacetail) - setlink(disc,next) - end - elseif prev and next then - setlink(prev,next) - if k_run(prevmarks,"emptyinjections",next,font,attr,...) then - done=true - end - setlink(prev,disc,next) - end - if done and trace_testruns then - report_disc("done",disc) - end - return nextstart,done -end -local function comprun(disc,c_run,...) - if trace_compruns then - report_disc("comp",disc) - end - local pre,post,replace=getdisc(disc) - local renewed=false - if pre then - sweepnode=disc - sweeptype="pre" - local new,done=c_run(pre,...) - if done then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,done=c_run(post,...) - if done then - post=new - renewed=true - end - end - if replace then - sweepnode=disc - sweeptype="replace" - local new,done=c_run(replace,...) - if done then - replace=new - renewed=true - end - end - sweepnode=nil - sweeptype=nil - if renewed then - if trace_testruns then - report_disc("done",disc) - end - setdisc(disc,pre,post,replace) - end - return getnext(disc),renewed -end -local function testrun(disc,t_run,c_run,...) - if trace_testruns then - report_disc("test",disc) - end - local prev,next=getboth(disc) - if not next then - return - end - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local renewed=false - if post or replace then - if post then - setlink(posttail,next) - else - post=next - end - if replace then - setlink(replacetail,next) - else - replace=next - end - local d_post=t_run(post,next,...) - local d_replace=t_run(replace,next,...) - if d_post>0 or d_replace>0 then - local d=d_replace>d_post and d_replace or d_post - local head=getnext(disc) - local tail=head - for i=2,d do - local nx=getnext(tail) - local id=getid(nx) - if id==disc_code then - head,tail=flattendisk(head,nx) - elseif id==glyph_code then - tail=nx - else - break - end - end - next=getnext(tail) - setnext(tail) - setprev(head) - local new=copy_node_list(head) - if posttail then - setlink(posttail,head) - else - post=head - end - if replacetail then - setlink(replacetail,new) - else - replace=new - end - else - if posttail then - setnext(posttail) - else - post=nil - end - if replacetail then - setnext(replacetail) - else - replace=nil - end - end - setlink(disc,next) - end - if trace_testruns then - report_disc("more",disc) - end - if pre then - sweepnode=disc - sweeptype="pre" - local new,ok=c_run(pre,...) - if ok then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,ok=c_run(post,...) - if ok then - post=new - renewed=true - end - end - if replace then - sweepnode=disc - sweeptype="replace" - local new,ok=c_run(replace,...) - if ok then - replace=new - renewed=true - end - end - sweepnode=nil - sweeptype=nil - if renewed then - setdisc(disc,pre,post,replace) - if trace_testruns then - report_disc("done",disc) - end - end - return getnext(disc),renewed -end -local nesting=0 -local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - local start - if sweep then - start=sweep - sweephead[head]=false - else - start=head - end - while start do - local char,id=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - end - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) - end - end - return head,done -end -local function t_run_single(start,stop,font,attr,lookupcache) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - local startnext=getnext(start) - if not a or (a==attr) then - local lookupmatch=lookupcache[char] - if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s,font) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - lookupmatch=lg - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end - else - end - else - end - if lastd then - return lastd - end - start=startnext - else - break - end - end - return 0 -end -local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getglyphdata(sub) - end - if not a or (a==attr) then - for n in nextnode,sub do - if n==last then - break - end - local char=ischar(n,font) - if char then - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end -end -local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - local start - if sweep then - start=sweep - sweephead[head]=false - else - start=head - end - while start do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) - end - end - return head,done -end -local function t_run_multiple(start,stop,font,attr,steps,nofsteps) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getglyphdata(start) - end - local startnext=getnext(start) - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getreplace(s) - if not s then - s=ss - ss=nil - end - end - lookupmatch=lg - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end - end - end - else - end - if lastd then - return lastd - end - start=startnext - else - break - end - end - return 0 -end -local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getglyphdata(sub) - end - if not a or (a==attr) then - for n in nextnode,sub do - if n==last then - break - end - local char=ischar(n) - if char then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end - end -end -local txtdirstate,pardirstate do - local getdirection=nuts.getdirection - txtdirstate=function(start,stack,top,rlparmode) - local dir,pop=getdirection(start) - if pop then - if top==1 then - return 0,rlparmode - else - top=top-1 - if stack[top]==righttoleft_code then - return top,-1 - else - return top,1 - end - end - elseif dir==lefttoright_code then - top=top+1 - stack[top]=lefttoright_code - return top,1 - elseif dir==righttoleft_code then - top=top+1 - stack[top]=righttoleft_code - return top,-1 - else - return top,rlparmode - end - end - pardirstate=function(start) - local dir=getdirection(start) - if dir==lefttoright_code then - return 1,1 - elseif dir==righttoleft_code then - return -1,-1 - else - return 0,0 - end - end -end -otf.helpers=otf.helpers or {} -otf.helpers.txtdirstate=txtdirstate -otf.helpers.pardirstate=pardirstate -do - local fastdisc=true - local testdics=false - directives.register("otf.fastdisc",function(v) fastdisc=v end) - local otfdataset=nil - local getfastdisc={ __index=function(t,k) - local v=usesfont(k,currentfont) - t[k]=v - return v - end } - local getfastspace={ __index=function(t,k) - local v=isspace(k,threshold) or false - t[k]=v - return v - end } - function otf.featuresprocessor(head,font,attr,direction,n) - local sequences=sequencelists[font] - nesting=nesting+1 - if nesting==1 then - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if not otfdataset then - otfdataset=otf.dataset - end - discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) - spaces=setmetatable({},getfastspace) - elseif currentfont~=font then - report_warning("nested call with a different font, level %s, quitting",nesting) - nesting=nesting-1 - return head,false - end - if trace_steps then - checkstep(head) - end - local initialrl=0 - if getid(head)==localpar_code and start_of_par(head) then - initialrl=pardirstate(head) - elseif direction==righttoleft_code then - initialrl=-1 - end - local datasets=otfdataset(tfmdata,font,attr) - local dirstack={ nil } - sweephead={} - for s=1,#datasets do - local dataset=datasets[s] - local attribute=dataset[2] - local sequence=dataset[3] - local rlparmode=initialrl - local topstack=0 - local typ=sequence.type - local gpossing=typ=="gpos_single" or typ=="gpos_pair" - local forcetestrun=typ=="gsub_ligature" - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local skiphash=sequence.skiphash - if not steps then - local h,ok=handler(head,dataset,sequence,initialrl,font,attr) - if h and h~=head then - head=h - end - elseif typ=="gsub_reversecontextchain" then - local start=find_node_tail(head) - local rlmode=0 - local merged=steps.merged - while start do - local char=ischar(start,font) - if char then - local m=merged[char] - if m then - local a - if attr then - a=getglyphdata(start) - end - if not a or (a==attr) then - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - break - end - end - end - if start then - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - end - else - local start=head - local rlmode=initialrl - if nofsteps==1 then - local step=steps[1] - local lookupcache=step.coverage - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local lookupmatch=lookupcache[char] - if lookupmatch then - local a - if attr then - if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then - a=true - end - elseif not attribute or getstate(start,attribute) then - a=true - end - if a then - local ok,df - head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - elseif start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - else - local merged=steps.merged - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local m=merged[char] - if m then - local a - if attr then - if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then - a=true - end - elseif not attribute or getstate(start,attribute) then - a=true - end - if a then - local ok,df - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if df then - break - elseif ok then - break - elseif not start then - break - end - end - end - if df then - elseif start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - end - end - if trace_steps then - registerstep(head) - end - end - nesting=nesting-1 - return head - end - function otf.datasetpositionprocessor(head,font,direction,dataset) - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if type(dataset)=="number" then - dataset=otfdataset(tfmdata,font,0)[dataset] - end - local sequence=dataset[3] - local typ=sequence.type - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local done=false - local dirstack={ nil } - local start=head - local initialrl=(direction==righttoleft_code) and -1 or 0 - local rlmode=initialrl - local rlparmode=initialrl - local topstack=0 - local merged=steps.merged - local position=0 - while start do - local char,id=ischar(start,font) - if char then - position=position+1 - local m=merged[char] - if m then - if skiphash and skiphash[char] then - start=getnext(start) - else - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - end - else - start=getnext(start) - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - start=getnext(start) - else - start=getnext(start) - end - end - return head - end -end -local plugins={} -otf.plugins=plugins -local report=logs.reporter("fonts") -function otf.registerplugin(name,f) - if type(name)=="string" and type(f)=="function" then - plugins[name]={ name,f } - report() - report("plugin %a has been loaded, please be aware of possible side effects",name) - report() - if logs.pushtarget then - logs.pushtarget("log") - end - report("Plugins are not officially supported unless stated otherwise. This is because") - report("they bypass the regular font handling and therefore some features in ConTeXt") - report("(especially those related to fonts) might not work as expected or might not work") - report("at all. Some plugins are for testing and development only and might change") - report("whenever we feel the need for it.") - report() - if logs.poptarget then - logs.poptarget() - end - end -end -function otf.plugininitializer(tfmdata,value) - if type(value)=="string" then - tfmdata.shared.plugin=plugins[value] - end -end -function otf.pluginprocessor(head,font,attr,direction) - local s=fontdata[font].shared - local p=s and s.plugin - if p then - if trace_plugins then - report_process("applying plugin %a",p[1]) - end - return p[2](head,font,attr,direction) - else - return head,false - end -end -function otf.featuresinitializer(tfmdata,value) -end -registerotffeature { - name="features", - description="features", - default=true, - initializers={ - position=1, - node=otf.featuresinitializer, - plug=otf.plugininitializer, - }, - processors={ - node=otf.featuresprocessor, - plug=otf.pluginprocessor, - } -} -local function markinitializer(tfmdata,value) - local properties=tfmdata.properties - properties.checkmarks=value -end -registerotffeature { - name="checkmarks", - description="check mark widths", - default=true, - initializers={ - node=markinitializer, - }, -} -otf.handlers=handlers -if context then - return -else -end -local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -local tag="kern" - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local shared=fontdata[font].shared - local features=shared and shared.features - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled - end -local function hasspacekerns(data) - local resources=data.resources - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps and sequence.features[tag] then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - return true - end - for k,v in next,coverage do - if v[32] then - return true - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - return true - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - return true - end - end - end - end - end - end - end - end - end - end - return false -end -otf.readers.registerextender { - name="spacekerns", - action=function(data) - data.properties.hasspacekerns=hasspacekerns(data) - end -} -local function spaceinitializer(tfmdata,value) - local resources=tfmdata.resources - local spacekerns=resources and resources.spacekerns - if value and spacekerns==nil then - local rawdata=tfmdata.shared and tfmdata.shared.rawdata - local properties=rawdata.properties - if properties and properties.hasspacekerns then - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - local left={} - local right={} - local last=0 - local feat=nil - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local kern=sequence.features[tag] - if kern then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - if feat then - for script,languages in next,kern do - local f=feat[script] - if f then - for l in next,languages do - f[l]=true - end - else - feat[script]=languages - end - end - else - feat=kern - end - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - right[k]=v - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - left[k]=kern - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - right[k]=one[3] - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - left[k]=one[3] - end - end - end - end - end - end - last=i - end - else - end - end - end - left=next(left) and left or false - right=next(right) and right or false - if left or right then - spacekerns={ - left=left, - right=right, - } - if last>0 then - local triggersequence={ - features={ [tag]=feat or { dflt={ dflt=true,} } }, - flags=noflags, - name="trigger_space_kerns", - order={ tag }, - type="trigger_space_kerns", - left=left, - right=right, - } - insert(sequences,last,triggersequence) - end - end - end - end - resources.spacekerns=spacekerns - end - return spacekerns -end -registerotffeature { - name="spacekern", - description="space kern injection", - default=true, - initializers={ - node=spaceinitializer, - }, -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] --- - -if not modules then modules={} end modules ['font-osd']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", - copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash -local next,type=next,type -local report=logs.reporter("otf","devanagari") -fonts=fonts or {} -fonts.analyzers=fonts.analyzers or {} -fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } -local otf=fonts.handlers.otf -local handlers=otf.handlers -local methods=fonts.analyzers.methods -local otffeatures=fonts.constructors.features.otf -local registerotffeature=otffeatures.register -local nuts=nodes.nuts -local getnext=nuts.getnext -local getprev=nuts.getprev -local getboth=nuts.getboth -local getid=nuts.getid -local getchar=nuts.getchar -local getfont=nuts.getfont -local getsubtype=nuts.getsubtype -local setlink=nuts.setlink -local setnext=nuts.setnext -local setprev=nuts.setprev -local setchar=nuts.setchar -local getprop=nuts.getprop -local setprop=nuts.setprop -local getstate=nuts.getstate -local setstate=nuts.setstate -local ischar=nuts.ischar -local insert_node_after=nuts.insert_after -local copy_node=nuts.copy -local remove_node=nuts.remove -local flush_list=nuts.flush_list -local flush_node=nuts.flush_node -local copyinjection=nodes.injections.copy -local unsetvalue=attributes.unsetvalue -local fontdata=fonts.hashes.identifiers -local a_syllabe=attributes.private('syllabe') -local dotted_circle=0x25CC -local c_nbsp=0x00A0 -local c_zwnj=0x200C -local c_zwj=0x200D -local states=fonts.analyzers.states -local s_rphf=states.rphf -local s_half=states.half -local s_pref=states.pref -local s_blwf=states.blwf -local s_pstf=states.pstf -local s_init=states.init -local replace_all_nbsp=nil -replace_all_nbsp=function(head) - replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) - return head - end - return replace_all_nbsp(head) -end -local processcharacters=nil -if context then - local fontprocesses=fonts.hashes.processes - function processcharacters(head,font) - local processors=fontprocesses[font] - for i=1,#processors do - head=processors[i](head,font,0) - end - return head - end -else - function processcharacters(head,font) - local processors=fontdata[font].shared.processes - for i=1,#processors do - head=processors[i](head,font,0) - end - return head - end -end -local indicgroups=characters and characters.indicgroups -if not indicgroups and characters then - local indic={ - c={}, - i={}, - d={}, - m={}, - s={}, - o={}, - } - local indicmarks={ - l={}, - t={}, - b={}, - r={}, - s={}, - } - local indicclasses={ - nukta={}, - halant={}, - ra={}, - anudatta={}, - } - local indicorders={ - bp={}, - ap={}, - bs={}, - as={}, - bh={}, - ah={}, - bm={}, - am={}, - } - for k,v in next,characters.data do - local i=v.indic - if i then - indic[i][k]=true - i=v.indicmark - if i then - if i=="s" then - local s=v.specials - indicmarks[i][k]={ s[2],s[3] } - else - indicmarks[i][k]=true - end - end - i=v.indicclass - if i then - indicclasses[i][k]=true - end - i=v.indicorder - if i then - indicorders[i][k]=true - end - end - end - indicgroups={ - consonant=indic.c, - independent_vowel=indic.i, - dependent_vowel=indic.d, - vowel_modifier=indic.m, - stress_tone_mark=indic.s, - pre_mark=indicmarks.l, - above_mark=indicmarks.t, - below_mark=indicmarks.b, - post_mark=indicmarks.r, - twopart_mark=indicmarks.s, - nukta=indicclasses.nukta, - halant=indicclasses.halant, - ra=indicclasses.ra, - anudatta=indicclasses.anudatta, - before_postscript=indicorders.bp, - after_postscript=indicorders.ap, - before_half=indicorders.bh, - after_half=indicorders.ah, - before_subscript=indicorders.bs, - after_subscript=indicorders.as, - before_main=indicorders.bm, - after_main=indicorders.am, - } - indic=nil - indicmarks=nil - indicclasses=nil - indicorders=nil - characters.indicgroups=indicgroups -end -local consonant=indicgroups.consonant -local independent_vowel=indicgroups.independent_vowel -local dependent_vowel=indicgroups.dependent_vowel -local vowel_modifier=indicgroups.vowel_modifier -local stress_tone_mark=indicgroups.stress_tone_mark -local pre_mark=indicgroups.pre_mark -local above_mark=indicgroups.above_mark -local below_mark=indicgroups.below_mark -local post_mark=indicgroups.post_mark -local twopart_mark=indicgroups.twopart_mark -local nukta=indicgroups.nukta -local halant=indicgroups.halant -local ra=indicgroups.ra -local anudatta=indicgroups.anudatta -local before_postscript=indicgroups.before_postscript -local after_postscript=indicgroups.after_postscript -local before_half=indicgroups.before_half -local after_half=indicgroups.after_half -local before_subscript=indicgroups.before_subscript -local after_subscript=indicgroups.after_subscript -local before_main=indicgroups.before_main -local after_main=indicgroups.after_main -local mark_four=table.merged ( - pre_mark, - above_mark, - below_mark, - post_mark -) -local mark_above_below_post=table.merged ( - above_mark, - below_mark, - post_mark -) -local zw_char={ - [c_zwnj]=true, - [c_zwj ]=true, -} -local dflt_true={ - dflt=true, -} -local two_defaults={} -local one_defaults={} -local false_flags={ false,false,false,false } -local sequence_reorder_matras={ - features={ dv01=two_defaults }, - flags=false_flags, - name="dv01_reorder_matras", - order={ "dv01" }, - type="devanagari_reorder_matras", - nofsteps=1, - steps={ - { - coverage=pre_mark, - } - } -} -local sequence_reorder_reph={ - features={ dv02=two_defaults }, - flags=false_flags, - name="dv02_reorder_reph", - order={ "dv02" }, - type="devanagari_reorder_reph", - nofsteps=1, - steps={ - { - coverage={}, - } - } -} -local sequence_reorder_pre_base_reordering_consonants={ - features={ dv03=one_defaults }, - flags=false_flags, - name="dv03_reorder_pre_base_reordering_consonants", - order={ "dv03" }, - type="devanagari_reorder_pre_base_reordering_consonants", - nofsteps=1, - steps={ - { - coverage={}, - } - } -} -local sequence_remove_joiners={ - features={ dv04=one_defaults }, - flags=false_flags, - name="dv04_remove_joiners", - order={ "dv04" }, - type="devanagari_remove_joiners", - nofsteps=1, - steps={ - { - coverage=zw_char, - }, - } -} -local basic_shaping_forms={ - akhn=true, - blwf=true, - cjct=true, - half=true, - nukt=true, - pref=true, - pstf=true, - rkrf=true, - rphf=true, - vatu=true, - locl=true, -} -local valid={ - abvs=true, - akhn=true, - blwf=true, - calt=true, - cjct=true, - half=true, - haln=true, - nukt=true, - pref=true, - pres=true, - pstf=true, - psts=true, - rkrf=true, - rphf=true, - vatu=true, - pres=true, - abvs=true, - blws=true, - psts=true, - haln=true, - calt=true, - locl=true, -} -local scripts={} -local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" } -local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" } -local nofscripts=#scripts_one -for i=1,nofscripts do - local one=scripts_one[i] - local two=scripts_two[i] - scripts[one]=true - scripts[two]=true - two_defaults[two]=dflt_true - one_defaults[one]=dflt_true - one_defaults[two]=dflt_true -end -local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end -local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end -local function initializedevanagi(tfmdata) - local script,language=otf.scriptandlanguage(tfmdata,attr) - if scripts[script] then - local resources=tfmdata.resources - local devanagari=resources.devanagari - if not devanagari then - report("adding devanagari features to font") - local gsubfeatures=resources.features.gsub - local sequences=resources.sequences - local sharedfeatures=tfmdata.shared.features - gsubfeatures["dv01"]=two_defaults - gsubfeatures["dv02"]=two_defaults - gsubfeatures["dv03"]=one_defaults - gsubfeatures["dv04"]=one_defaults - local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) - local reorder_reph=copy(sequence_reorder_reph) - local reorder_matras=copy(sequence_reorder_matras) - local remove_joiners=copy(sequence_remove_joiners) - local lastmatch=0 - for s=1,#sequences do - local features=sequences[s].features - if features then - for k,v in next,features do - if k=="locl" then - local steps=sequences[s].steps - local nofsteps=sequences[s].nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,pre_mark do - local locl=coverage[k] - if locl then - if #locl>0 then - for j=1,#locl do - local ck=locl[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - locl=coverage[k] - end - end - end - end - end - end - if locl then - reorder_matras.steps[1].coverage[locl]=true - end - end - end - end - end - end - if basic_shaping_forms[k] then - lastmatch=lastmatch+1 - if s~=lastmatch then - table.insert(sequences,lastmatch,table.remove(sequences,s)) - end - end - end - end - end - local insertindex=lastmatch+1 - if tfmdata.properties.language then - dflt_true[tfmdata.properties.language]=true - end - insert(sequences,insertindex,reorder_pre_base_reordering_consonants) - insert(sequences,insertindex,reorder_reph) - insert(sequences,insertindex,reorder_matras) - insert(sequences,insertindex,remove_joiners) - local blwfcache={} - local vatucache={} - local pstfcache={} - local seqsubset={} - local rephstep={ - coverage={} - } - local devanagari={ - reph=false, - vattu=false, - blwfcache=blwfcache, - vatucache=vatucache, - pstfcache=pstfcache, - seqsubset=seqsubset, - reorderreph=rephstep, - } - reorder_reph.steps={ rephstep } - local pre_base_reordering_consonants={} - reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants - resources.devanagari=devanagari - for s=1,#sequences do - local sequence=sequences[s] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local features=sequence.features - local has_rphf=features.rphf - local has_blwf=features.blwf - local has_vatu=features.vatu - local has_pstf=features.pstf - if has_rphf and has_rphf[script] then - devanagari.reph=true - elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then - devanagari.vattu=true - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,coverage do - for h,w in next,halant do - if v[h] then - if not blwfcache[k] then - blwfcache[k]=v - end - end - if has_vatu and has_vatu[script] and not vatucache[k] then - vatucache[k]=v - end - end - end - end - end - elseif has_pstf and has_pstf[script] then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,coverage do - if not pstfcache[k] then - pstfcache[k]=v - end - end - for k,v in next,ra do - local r=coverage[k] - if r then - local found=false - if #r>0 then - for j=1,#r do - local ck=r[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups and chainlookups[f] then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local h=coverage[k] - if h then - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - if found then - break - end - end - end - end - end - end - end - else - for k,v in next,r do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - end - if found then - break - end - end - end - end - end - end - for kind,spec in next,features do - if valid[kind] and valid_two(spec)then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local reph,rephbase=false,false - if kind=="rphf" then - for k,v in next,ra do - local r=coverage[k] - if r then - rephbase=k - local h=false - if #r>0 then - for j=1,#r do - local ck=r[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local r=coverage[k] - if r then - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - if h then - break - end - end - end - end - end - end - end - else - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - end - if reph then - break - end - end - end - end - seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase } - end - end - end - if kind=="pref" then - local steps=sequence.steps - local nofsteps=sequence.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,halant do - local h=coverage[k] - if h then - local found=false - if #h>0 then - for j=1,#h do - local ck=h[j] - local f=ck[4] - local chainlookups=ck[6] - if chainlookups then - local chainlookup=chainlookups[f] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local steps=chainstep.steps - local nofsteps=chainstep.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local h=coverage[k] - if h then - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - if found then - break - end - end - end - end - end - end - end - else - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[found]=true - break - end - end - end - if found then - break - end - end - end - end - end - end - end - end - if two_defaults[script] then - sharedfeatures["dv01"]=true - sharedfeatures["dv02"]=true - sharedfeatures["dv03"]=true - sharedfeatures["dv04"]=true - elseif one_defaults[script] then - sharedfeatures["dv03"]=true - sharedfeatures["dv04"]=true - end - if script=="mlym" or script=="taml" then - devanagari.left_matra_before_base=true - end - end - end -end -registerotffeature { - name="devanagari", - description="inject additional features", - default=true, - initializers={ - node=initializedevanagi, - }, -} -local show_syntax_errors=false -local function inject_syntax_error(head,current,char) - local signal=copy_node(current) - copyinjection(signal,current) - if pre_mark[char] then - setchar(signal,dotted_circle) - else - setchar(current,dotted_circle) - end - return insert_node_after(head,current,signal) -end -local function initialize_one(font,attr) - local tfmdata=fontdata[font] - local datasets=otf.dataset(tfmdata,font,attr) - local devanagaridata=datasets.devanagari - if not devanagaridata then - devanagaridata={ - reph=false, - vattu=false, - blwfcache={}, - vatucache={}, - pstfcache={}, - } - datasets.devanagari=devanagaridata - local resources=tfmdata.resources - local devanagari=resources.devanagari - for s=1,#datasets do - local dataset=datasets[s] - if dataset and dataset[1] then - local kind=dataset[4] - if kind=="rphf" then - devanagaridata.reph=true - elseif kind=="blwf" or kind=="vatu" then - devanagaridata.vattu=true - devanagaridata.blwfcache=devanagari.blwfcache - devanagaridata.vatucache=devanagari.vatucache - devanagaridata.pstfcache=devanagari.pstfcache - end - end - end - end - return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache -end -local function contextchain(contexts,n) - local char=getchar(n) - for k=1,#contexts do - local ck=contexts[k] - local seq=ck[3] - local f=ck[4] - local l=ck[5] - if (l-f)==1 and seq[f+1][char] then - local ok=true - local c=n - for i=l+1,#seq do - c=getnext(c) - if not c or not seq[i][ischar(c)] then - ok=false - break - end - end - if ok then - c=getprev(n) - for i=1,f-1 do - c=getprev(c) - if not c or not seq[f-i][ischar(c)] then - ok=false - end - end - end - if ok then - return true - end - end - end - return false -end -local function order_matras(c) - local cn=getnext(c) - local char=getchar(cn) - while dependent_vowel[char] do - local next=getnext(cn) - local cc=c - local cchar=getchar(cc) - while cc~=cn do - if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - setnext(getprev(cc),cn) - setprev(cn,getprev(cc)) - setnext(cn,cc) - setprev(cc,cn) - break - end - cc=getnext(cc) - cchar=getchar(cc) - end - cn=next - char=getchar(cn) - end -end -local function reorder_one(head,start,stop,font,attr,nbspaces) - local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr) - local devanagari=fontdata[font].resources.devanagari - local current=start - local n=getnext(start) - local base=nil - local firstcons=nil - local lastcons=nil - local basefound=false - if reph and ra[getchar(start)] and halant[getchar(n)] then - if n==stop then - return head,stop,nbspaces - end - if getchar(getnext(n))==c_zwj then - current=start - else - current=getnext(n) - setstate(start,s_rphf) - end - end - if getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - firstcons=current - lastcons=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj and current~=stop then - local next=getnext(current) - if next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=next and getnext(next) or nil - local changestop=next==stop - local tempcurrent=copy_node(next) - copyinjection(tempcurrent,next) - local nextcurrent=copy_node(current) - copyinjection(nextcurrent,current) - setlink(tempcurrent,nextcurrent) - setstate(tempcurrent,s_blwf) - tempcurrent=processcharacters(tempcurrent,font) - setstate(tempcurrent,unsetvalue) - if getchar(next)==getchar(tempcurrent) then - flush_list(tempcurrent) - if show_syntax_errors then - head,current=inject_syntax_error(head,current,char) - end - else - setchar(current,getchar(tempcurrent)) - local freenode=getnext(current) - setlink(current,tmp) - flush_node(freenode) - flush_list(tempcurrent) - if changestop then - stop=current - end - end - end - end - end - end - end - while not basefound do - local char=getchar(current) - if consonant[char] then - setstate(current,s_half) - if not firstcons then - firstcons=current - end - lastcons=current - if not base then - base=current - elseif blwfcache[char] then - setstate(current,s_blwf) - elseif pstfcache[char] then - setstate(current,s_pstf) - else - base=current - end - end - basefound=current==stop - current=getnext(current) - end - if base~=lastcons then - local np=base - local n=getnext(base) - local ch=getchar(n) - if nukta[ch] then - np=n - n=getnext(n) - ch=getchar(n) - end - if halant[ch] then - if lastcons~=stop then - local ln=getnext(lastcons) - if nukta[getchar(ln)] then - lastcons=ln - end - end - local nn=getnext(n) - local ln=getnext(lastcons) - setlink(np,nn) - setnext(lastcons,n) - if ln then - setprev(ln,n) - end - setnext(n,ln) - setprev(n,lastcons) - if lastcons==stop then - stop=n - end - end - end - n=getnext(start) - if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then - local matra=base - if base~=stop then - local next=getnext(base) - if dependent_vowel[getchar(next)] then - matra=next - end - end - local sp=getprev(start) - local nn=getnext(n) - local mn=getnext(matra) - setlink(sp,nn) - setlink(matra,start) - setlink(n,mn) - if head==start then - head=nn - end - start=nn - if matra==stop then - stop=n - end - end - local current=start - while current~=stop do - local next=getnext(current) - if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then - setstate(current,unsetvalue) - end - current=next - end - if base~=stop and getstate(base) then - local next=getnext(base) - if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then - setstate(base,unsetvalue) - end - end - local current,allreordered,moved=start,false,{ [base]=true } - local a,b,p,bn=base,base,base,getnext(base) - if base~=stop and nukta[getchar(bn)] then - a,b,p=bn,bn,bn - end - while not allreordered do - local c=current - local n=getnext(current) - local l=nil - if c~=stop then - local ch=getchar(n) - if nukta[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if halant[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - local tpm=twopart_mark[ch] - while tpm do - local extra=copy_node(n) - copyinjection(extra,n) - ch=tpm[1] - setchar(n,ch) - setchar(extra,tpm[2]) - head=insert_node_after(head,current,extra) - tpm=twopart_mark[ch] - end - while c~=stop and dependent_vowel[ch] do - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if vowel_modifier[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop and stress_tone_mark[ch] then - c=n - n=getnext(n) - end - end - end - end - local bp=getprev(firstcons) - local cn=getnext(current) - local last=getnext(c) - while cn~=last do - if pre_mark[getchar(cn)] then - if devanagari.left_matra_before_base then - local prev,next=getboth(cn) - setlink(prev,next) - if cn==stop then - stop=getprev(cn) - end - if base==start then - if head==start then - head=cn - end - start=cn - end - setlink(getprev(base),cn) - setlink(cn,base) - cn=next - else - if bp then - setnext(bp,cn) - end - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - if cn==stop then - stop=prev - end - setprev(cn,bp) - setlink(cn,firstcons) - if firstcons==start then - if head==start then - head=cn - end - start=cn - end - cn=next - end - elseif current~=base and dependent_vowel[getchar(cn)] then - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - if cn==stop then - stop=prev - end - setlink(b,cn,getnext(b)) - order_matras(cn) - cn=next - elseif current==base and dependent_vowel[getchar(cn)] then - local cnn=getnext(cn) - order_matras(cn) - cn=cnn - while cn~=last and dependent_vowel[getchar(cn)] do - cn=getnext(cn) - end - else - cn=getnext(cn) - end - end - allreordered=c==stop - current=getnext(c) - end - if reph or vattu then - local current,cns=start,nil - while current~=stop do - local c=current - local n=getnext(current) - if ra[getchar(current)] and halant[getchar(n)] then - c=n - n=getnext(n) - local b,bn=base,base - while bn~=stop do - local next=getnext(bn) - if dependent_vowel[getchar(next)] then - b=next - end - bn=next - end - if getstate(current,s_rphf) then - if b~=current then - if current==start then - if head==start then - head=n - end - start=n - end - if b==stop then - stop=c - end - local prev=getprev(current) - setlink(prev,n) - local next=getnext(b) - setlink(c,next) - setlink(b,current) - end - elseif cns and getnext(cns)~=current then - local cp=getprev(current) - local cnsn=getnext(cns) - setlink(cp,n) - setlink(cns,current) - setlink(c,cnsn) - if c==stop then - stop=cp - break - end - current=getprev(n) - end - else - local char=getchar(current) - if consonant[char] then - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - if not vatucache[char] then - next=getnext(cns) - while dependent_vowel[getchar(next)] do - cns=next - next=getnext(cns) - end - end - elseif char==c_nbsp then - nbspaces=nbspaces+1 - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - if not vatucache[char] then - next=getnext(cns) - while dependent_vowel[getchar(next)] do - cns=next - next=getnext(cns) - end - end - end - end - current=getnext(current) - end - end - if getchar(base)==c_nbsp then - nbspaces=nbspaces-1 - if base==stop then - stop=getprev(stop) - end - head=remove_node(head,base) - flush_node(base) - end - return head,stop,nbspaces -end -function handlers.devanagari_reorder_matras(head,start) - local current=start - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - local next=getnext(current) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - if next then - local char=ischar(next,startfont) - if char and zw_char[char] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - local startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - break - end - else - break - end - current=next - end - return head,start,true -end -local rephbase={} -function handlers.devanagari_reorder_reph(head,start) - local current=getnext(start) - local startnext=nil - local startprev=nil - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - ::step_1:: - local char=ischar(start,startfont) - local rephbase=rephbase[startfont][char] - if char and after_subscript[rephbase] then - goto step_5 - end - ::step_2:: - if char and not after_postscript[rephbase] then - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - local next=getnext(current) - if next then - local nextchar=ischar(next,startfont) - if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break - end - end - end - ::step_3:: - if not startnext then - if char and after_main[rephbase] then - current=getnext(start) - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if consonant[char] and not getstate(current,s_pref) then - startnext=getnext(start) - head=remove_node(head,start) - setlink(current,start) - setlink(start,getnext(current)) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break - end - end - end - end - ::step_4:: - if not startnext then - if char and before_postscript[rephbase] then - current=getnext(start) - local c=nil - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if getstate(current,s_pstf) then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(current),start) - setlink(start,current) - start=startnext - startattr=getprop(start,a_syllabe) - break - elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then - c=current - end - current=getnext(current) - else - if c then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(c),start) - setlink(start,c) - start=startnext - startattr=getprop(start,a_syllabe) - end - break - end - end - end - end - ::step_5:: - if not startnext then - current=getnext(start) - local c=nil - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - local state=getstate(current) - if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then - c=current - elseif after_subscript[rephbase] and (state==s_pstf) then - c=current - end - current=getnext(current) - else - break - end - end - if c then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(c),start) - setlink(start,c) - start=startnext - startattr=getprop(start,a_syllabe) - end - end - ::step_6:: - if not startnext then - current=start - local next=getnext(current) - while next do - local nextchar=ischar(next,startfont) - if nextchar and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - else - break - end - end - if start~=current then - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,getnext(current)) - setlink(current,start) - start=startnext - end - end - return head,start,true -end -local reordered_pre_base_reordering_consonants={} -function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) - if reordered_pre_base_reordering_consonants[start] then - return head,start,true - end - local current=start - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - local next=getnext(current) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] then - if next then - local char=ischar(next,startfont) - if char and zw_char[char] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - local startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - reordered_pre_base_reordering_consonants[start]=true - start=startnext - return head,start,true - end - else - break - end - current=next - end - local startattr=getprop(start,a_syllabe) - local current=getprev(start) - while current and getprop(current,a_syllabe)==startattr do - local char=ischar(current) - if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then - startnext=getnext(start) - head=remove_node(head,start) - if current==head then - setlink(start,current) - head=start - else - setlink(getprev(current),start) - setlink(start,current) - end - reordered_pre_base_reordering_consonants[start]=true - start=startnext - break - end - current=getprev(current) - end - return head,start,true -end -function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement) - local stop=getnext(start) - local font=getfont(start) - local last=start - while stop do - local char=ischar(stop,font) - if char and (char==c_zwnj or char==c_zwj) then - last=stop - stop=getnext(stop) - else - break - end - end - local prev=getprev(start) - if stop then - setnext(last) - setlink(prev,stop) - elseif prev then - setnext(prev) - end - if head==start then - head=stop - end - flush_list(start) - return head,stop,true -end -local function initialize_two(font,attr) - local devanagari=fontdata[font].resources.devanagari - if devanagari then - return devanagari.seqsubset or {},devanagari.reorderreph or {} - else - return {},{} - end -end -local function reorder_two(head,start,stop,font,attr,nbspaces) - local seqsubset,reorderreph=initialize_two(font,attr) - local halfpos=nil - local basepos=nil - local subpos=nil - local postpos=nil - reorderreph.coverage={} - rephbase[font]={} - for i=1,#seqsubset do - local subset=seqsubset[i] - local kind=subset[1] - local lookupcache=subset[2] - if kind=="rphf" then - reorderreph.coverage[subset[3]]=true - rephbase[font][subset[3]]=subset[4] - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - local afternext=next~=stop and getnext(next) - if afternext and zw_char[getchar(afternext)] then - current=afternext - elseif current==start then - setstate(current,s_rphf) - current=next - else - current=next - end - end - end - end - current=getnext(current) - end - elseif kind=="pref" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_pref) - setstate(next,s_pref) - current=next - end - end - end - end - current=getnext(current) - end - elseif kind=="half" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if next~=stop and getchar(getnext(next))==c_zwnj then - current=next - elseif (not getstate(current)) then - setstate(current,s_half) - if not halfpos then - halfpos=current - end - end - current=getnext(current) - end - end - end - current=getnext(current) - end - elseif kind=="blwf" or kind=="vatu" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_blwf) - setstate(next,s_blwf) - current=next - subpos=current - end - end - end - end - current=getnext(current) - end - elseif kind=="pstf" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - if found[getchar(next)] or contextchain(found,next) then - if (not getstate(current) and not getstate(next)) then - setstate(current,s_pstf) - setstate(next,s_pstf) - current=next - postpos=current - end - end - end - end - current=getnext(current) - end - end - end - local current,base,firstcons=start,nil,nil - if getstate(start,s_rphf) then - current=getnext(getnext(start)) - end - if current~=getnext(stop) and getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj then - local next=getnext(current) - if current~=stop and next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=getnext(next) - local changestop=next==stop - setnext(next) - setstate(current,s_pref) - current=processcharacters(current,font) - setstate(current,s_blwf) - current=processcharacters(current,font) - setstate(current,s_pstf) - current=processcharacters(current,font) - setstate(current,unsetvalue) - if halant[getchar(current)] then - setnext(getnext(current),tmp) - if show_syntax_errors then - head,current=inject_syntax_error(head,current,char) - end - else - setnext(current,tmp) - if changestop then - stop=current - end - end - end - end - end - end - else - local last=getnext(stop) - while current~=last do - local next=getnext(current) - if consonant[getchar(current)] then - if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then - if not firstcons then - firstcons=current - end - local a=getstate(current) - if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then - base=current - end - end - end - current=next - end - if not base then - base=firstcons - end - end - if not base then - if getstate(start,s_rphf) then - setstate(start,unsetvalue) - end - return head,stop,nbspaces - else - if getstate(base) then - setstate(base,unsetvalue) - end - basepos=base - end - if not halfpos then - halfpos=base - end - if not subpos then - subpos=base - end - if not postpos then - postpos=subpos or base - end - local moved={} - local current=start - local last=getnext(stop) - while current~=last do - local char=getchar(current) - local target=nil - local cn=getnext(current) - local tpm=twopart_mark[char] - while tpm do - local extra=copy_node(current) - copyinjection(extra,current) - char=tpm[1] - setchar(current,char) - setchar(extra,tpm[2]) - head=insert_node_after(head,current,extra) - tpm=twopart_mark[char] - end - if not moved[current] and dependent_vowel[char] then - if pre_mark[char] then - moved[current]=true - local prev,next=getboth(current) - setlink(prev,next) - if current==stop then - stop=getprev(current) - end - local pos - if before_main[char] then - pos=basepos - else - pos=halfpos - end - local ppos=getprev(pos) - while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do - if getstate(ppos,s_pref) then - pos=ppos - end - ppos=getprev(ppos) - end - local ppos=getprev(pos) - while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do - ppos=getprev(ppos) - if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then - pos=ppos - ppos=getprev(ppos) - else - break - end - end - if pos==start then - if head==start then - head=current - end - start=current - end - setlink(getprev(pos),current) - setlink(current,pos) - elseif above_mark[char] then - target=basepos - if subpos==basepos then - subpos=current - end - if postpos==basepos then - postpos=current - end - basepos=current - elseif below_mark[char] then - target=subpos - if postpos==subpos then - postpos=current - end - subpos=current - elseif post_mark[char] then - local n=getnext(postpos) - while n do - local v=ischar(n,font) - if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then - postpos=n - else - break - end - n=getnext(n) - end - target=postpos - postpos=current - end - if mark_above_below_post[char] then - local prev=getprev(current) - if prev~=target then - local next=getnext(current) - setlink(prev,next) - if current==stop then - stop=prev - end - setlink(current,getnext(target)) - setlink(target,current) - end - end - end - current=cn - end - local current=getnext(start) - local last=getnext(stop) - while current~=last do - local char=getchar(current) - local cn=getnext(current) - if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then - if after_main[ischar(cn)] then - local prev=getprev(current) - local next=getnext(cn) - local bpn=getnext(basepos) - while bpn and dependent_vowel[ischar(bpn)] do - basepos=bpn - bpn=getnext(bpn) - end - if basepos~=prev then - setlink(prev,next) - setlink(cn,getnext(basepos)) - setlink(basepos,current) - if cn==stop then - stop=prev - end - cn=next - end - end - end - current=cn - end - local current=start - local c=nil - while current~=stop do - local char=getchar(current) - if halant[char] or stress_tone_mark[char] then - if not c then - c=current - end - else - c=nil - end - local next=getnext(current) - if c and nukta[getchar(next)] then - if head==c then - head=next - end - if stop==next then - stop=current - end - setlink(getprev(c),next) - local nextnext=getnext(next) - setnext(current,nextnext) - local nextnextnext=getnext(nextnext) - if nextnextnext then - setprev(nextnextnext,current) - end - setlink(nextnext,c) - end - if stop==current then break end - current=getnext(current) - end - if getchar(base)==c_nbsp then - if base==stop then - stop=getprev(stop) - end - nbspaces=nbspaces-1 - head=remove_node(head,base) - flush_node(base) - end - return head,stop,nbspaces -end -local separator={} -imerge(separator,consonant) -imerge(separator,independent_vowel) -imerge(separator,dependent_vowel) -imerge(separator,vowel_modifier) -imerge(separator,stress_tone_mark) -for k,v in next,nukta do separator[k]=true end -for k,v in next,halant do separator[k]=true end -local function analyze_next_chars_one(c,font,variant) - local n=getnext(c) - if not n then - return c - end - if variant==1 then - local v=ischar(n,font) - if v and nukta[v] then - n=getnext(n) - if n then - v=ischar(n,font) - end - end - if n and v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv then - if vv==c_zwj and consonant[vvv] then - c=nnn - elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then - local nnnn=getnext(nnn) - if nnnn then - local vvvv=ischar(nnnn,font) - if vvvv and consonant[vvvv] then - c=nnnn - end - end - end - end - end - end - end - end - elseif variant==2 then - local v=ischar(n,font) - if v and nukta[v] then - c=n - end - n=getnext(c) - if n then - v=ischar(n,font) - if v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and zw_char[v] then - n=nn - v=vv - nn=getnext(nn) - vv=nn and ischar(nn,font) - end - if vv and halant[v] and consonant[vv] then - c=nn - end - end - end - end - end - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if not v then - return c - end - local already_pre_mark - local already_above_mark - local already_below_mark - local already_post_mark - while dependent_vowel[v] do - local vowels=twopart_mark[v] or { v } - for k,v in next,vowels do - if pre_mark[v] and not already_pre_mark then - already_pre_mark=true - elseif above_mark[v] and not already_above_mark then - already_above_mark=true - elseif below_mark[v] and not already_below_mark then - already_below_mark=true - elseif post_mark[v] and not already_post_mark then - already_post_mark=true - else - return c - end - end - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if nukta[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if vowel_modifier[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - return n - else - return c - end -end -local function analyze_next_chars_two(c,font) - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if v and nukta[v] then - c=n - end - n=c - while true do - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv then - if halant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and zw_char[vvv] then - n=nnn - end - end - elseif vv==c_zwnj or vv==c_zwj then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and halant[vvv] then - n=nnn - end - end - else - break - end - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and consonant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and nukta[vvv] then - n=nnn - end - end - c=n - else - break - end - else - break - end - else - break - end - else - break - end - end - if not c then - return - end - local n=getnext(c) - if not n then - return c - end - local v=ischar(n,font) - if not v then - return c - end - if anudatta[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - if v==c_zwnj or v==c_zwj then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - else - local already_pre_mark - local already_above_mark - local already_below_mark - local already_post_mark - while dependent_vowel[v] do - local vowels=twopart_mark[v] or { v } - for k,v in next,vowels do - if pre_mark[v] and not already_pre_mark then - already_pre_mark=true - elseif above_mark[v] and not already_above_mark then - already_above_mark=true - elseif below_mark[v] and not already_below_mark then - already_below_mark=true - elseif post_mark[v] and not already_post_mark then - already_post_mark=true - else - return c - end - end - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if nukta[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if halant[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - end - if vowel_modifier[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end - end - if stress_tone_mark[v] then - return n - else - return c - end -end -local function method_one(head,font,attr) - local current=head - local start=true - local done=false - local nbspaces=0 - local syllabe=0 - while current do - local char=ischar(current,font) - if char then - done=true - local syllablestart=current - local syllableend=nil - local c=current - local n=getnext(c) - local first=char - if n and ra[first] then - local second=ischar(n,font) - if second and halant[second] then - local n=getnext(n) - if n then - local third=ischar(n,font) - if third then - c=n - first=third - end - end - end - end - local standalone=first==c_nbsp - if standalone then - local prev=getprev(current) - if prev then - local prevchar=ischar(prev,font) - if not prevchar then - elseif not separator[prevchar] then - else - standalone=false - end - else - end - end - if standalone then - local syllableend=analyze_next_chars_one(c,font,2) - current=getnext(syllableend) - if syllablestart~=syllableend then - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - else - if consonant[char] then - local prevc=true - while prevc do - prevc=false - local n=getnext(current) - if not n then - break - end - local v=ischar(n,font) - if not v then - break - end - if nukta[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if halant[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - if v==c_zwnj or v==c_zwj then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if consonant[v] then - prevc=true - current=n - end - end - end - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and nukta[v] then - current=n - n=getnext(current) - end - end - syllableend=current - current=n - if current then - local v=ischar(current,font) - if not v then - elseif halant[v] then - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and zw_char[v] then - syllableend=n - current=getnext(n) - else - syllableend=current - current=n - end - else - syllableend=current - current=n - end - else - if dependent_vowel[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - if syllablestart~=syllableend then - if syllableend then - syllabe=syllabe+1 - local c=syllablestart - local n=getnext(syllableend) - while c~=n do - setprop(c,a_syllabe,syllabe) - c=getnext(c) - end - end - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - elseif independent_vowel[char] then - syllableend=current - current=getnext(current) - if current then - local v=ischar(current,font) - if v then - if vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - else - if show_syntax_errors then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - current=getnext(current) - end - end - else - current=getnext(current) - end - start=false - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - current=head - local n=0 - while current do - local char=ischar(current,font) - if char then - if n==0 and not getstate(current) then - setstate(current,s_init) - end - n=n+1 - else - n=0 - end - current=getnext(current) - end - return head,done -end -local function method_two(head,font,attr) - local current=head - local start=true - local done=false - local syllabe=0 - local nbspaces=0 - while current do - local syllablestart=nil - local syllableend=nil - local char=ischar(current,font) - if char then - done=true - syllablestart=current - local c=current - local n=getnext(current) - if n and ra[char] then - local nextchar=ischar(n,font) - if nextchar and halant[nextchar] then - local n=getnext(n) - if n then - local nextnextchar=ischar(n,font) - if nextnextchar then - c=n - char=nextnextchar - end - end - end - end - if independent_vowel[char] then - current=analyze_next_chars_one(c,font,1) - syllableend=current - else - local standalone=char==c_nbsp - if standalone then - nbspaces=nbspaces+1 - local p=getprev(current) - if not p then - elseif ischar(p,font) then - elseif not separator[getchar(p)] then - else - standalone=false - end - end - if standalone then - current=analyze_next_chars_one(c,font,2) - syllableend=current - elseif consonant[getchar(current)] then - current=analyze_next_chars_two(current,font) - syllableend=current - end - end - end - if syllableend then - syllabe=syllabe+1 - local c=syllablestart - local n=getnext(syllableend) - while c~=n do - setprop(c,a_syllabe,syllabe) - c=getnext(c) - end - end - if syllableend and syllablestart~=syllableend then - head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) - end - if not syllableend and show_syntax_errors then - local char=ischar(current,font) - if char and not getstate(current) then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - end - start=false - current=getnext(current) - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - current=head - local n=0 - while current do - local char=ischar(current,font) - if char then - if n==0 and not getstate(current) then - setstate(current,s_init) - end - n=n+1 - else - n=0 - end - current=getnext(current) - end - return head,done -end -for i=1,nofscripts do - methods[scripts_one[i]]=method_one - methods[scripts_two[i]]=method_two -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl” ab81576f20e2d37bc8707e1dbd3decf2] --- - -if not modules then modules={} end modules ['font-ocl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tostring,tonumber,next=tostring,tonumber,next -local round,max=math.round,math.round -local gsub,find=string.gsub,string.find -local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat -local setmetatableindex=table.setmetatableindex -local formatters=string.formatters -local tounicode=fonts.mappings.tounicode -local helpers=fonts.helpers -local charcommand=helpers.commands.char -local rightcommand=helpers.commands.right -local leftcommand=helpers.commands.left -local downcommand=helpers.commands.down -local otf=fonts.handlers.otf -local otfregister=otf.features.register -local f_color=formatters["%.3f %.3f %.3f rg"] -local f_gray=formatters["%.3f g"] -if context then - local startactualtext=nil - local stopactualtext=nil - function otf.getactualtext(s) - if not startactualtext then - startactualtext=backends.codeinjections.startunicodetoactualtextdirect - stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect - end - return startactualtext(s),stopactualtext() - end -else - local tounicode=fonts.mappings.tounicode16 - function otf.getactualtext(s) - return - "/Span << /ActualText >> BDC", - "EMC" - end -end -local sharedpalettes={} -local hash=setmetatableindex(function(t,k) - local v={ "pdf","direct",k } - t[k]=v - return v -end) -if context then - local colors=attributes.list[attributes.private('color')] or {} - local transparencies=attributes.list[attributes.private('transparency')] or {} - function otf.registerpalette(name,values) - sharedpalettes[name]=values - local color=lpdf.color - local transparency=lpdf.transparency - local register=colors.register - for i=1,#values do - local v=values[i] - if v=="textcolor" then - values[i]=false - else - local c=nil - local t=nil - if type(v)=="table" then - c=register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) - else - c=colors[v] - t=transparencies[v] - end - if c and t then - values[i]=hash[color(1,c).." "..transparency(t)] - elseif c then - values[i]=hash[color(1,c)] - elseif t then - values[i]=hash[color(1,t)] - end - end - end - end -else - function otf.registerpalette(name,values) - sharedpalettes[name]=values - for i=1,#values do - local v=values[i] - if v then - values[i]=hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] - end - end - end -end -local function convert(t,k) - local v={} - for i=1,#k do - local p=k[i] - local r,g,b=p[1],p[2],p[3] - if r==g and g==b then - v[i]=hash[f_gray(r/255)] - else - v[i]=hash[f_color(r/255,g/255,b/255)] - end - end - t[k]=v - return v -end -local mode={ "pdf","mode","font" } -local push={ "pdf","page","q" } -local pop={ "pdf","page","Q" } -local function initializeoverlay(tfmdata,kind,value) - if value then - local resources=tfmdata.resources - local palettes=resources.colorpalettes - if palettes then - local converted=resources.converted - if not converted then - converted=setmetatableindex(convert) - resources.converted=converted - end - local colorvalues=sharedpalettes[value] - local default=false - if colorvalues then - default=colorvalues[#colorvalues] - else - colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} - end - local classes=#colorvalues - if classes==0 then - return - end - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local properties=tfmdata.properties - properties.virtualized=true - tfmdata.fonts={ - { id=0 } - } - local getactualtext=otf.getactualtext - local b,e=getactualtext(tounicode(0xFFFD)) - local actualb={ "pdf","page",b } - local actuale={ "pdf","page",e } - for unicode,character in next,characters do - local description=descriptions[unicode] - if description then - local colorlist=description.colors - if colorlist then - local u=description.unicode or characters[unicode].unicode - local w=character.width or 0 - local s=#colorlist - local goback=w~=0 and leftcommand[w] or nil - local t={ - mode, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, - push, - } - local n=3 - local l=nil - for i=1,s do - local entry=colorlist[i] - local v=colorvalues[entry.class] or default - if v and l~=v then - n=n+1 t[n]=v - l=v - end - n=n+1 t[n]=charcommand[entry.slot] - if s>1 and i temp-otf-svg-shape.log","w") - end - end - local new=nil - local function inkscapeformat(suffix) - if new==nil then - new=os.resultof("inkscape --version") or "" - new=new=="" or not find(new,"Inkscape%s*0") - end - return new and "filename" or suffix - end - function otfsvg.topdf(svgshapes,tfmdata) - local pdfshapes={} - local inkscape=runner() - if inkscape then - local descriptions=tfmdata.descriptions - local nofshapes=#svgshapes - local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] - local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] - local f_convert=formatters["%s --export-%s=%s\n"] - local filterglyph=otfsvg.filterglyph - local nofdone=0 - local processed={} - report_svg("processing %i svg containers",nofshapes) - statistics.starttiming() - for i=1,nofshapes do - local entry=svgshapes[i] - for index=entry.first,entry.last do - local data=filterglyph(entry,index) - if data and data~="" then - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - savedata(svgfile,data) - inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile)) - processed[index]=true - nofdone=nofdone+1 - if nofdone%25==0 then - report_svg("%i shapes submitted",nofdone) - end - end - end - end - if nofdone%25~=0 then - report_svg("%i shapes submitted",nofdone) - end - report_svg("processing can be going on for a while") - inkscape:write("quit\n") - inkscape:close() - report_svg("processing %i pdf results",nofshapes) - for index in next,processed do - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - local pdfdata=loaddata(pdffile) - if pdfdata and pdfdata~="" then - pdfshapes[index]={ - data=pdfdata, - } - end - remove(svgfile) - remove(pdffile) - end - local characters=tfmdata.characters - for k,v in next,characters do - local d=descriptions[k] - local i=d.index - if i then - local p=pdfshapes[i] - if p then - local w=d.width - local l=d.boundingbox[1] - local r=d.boundingbox[3] - p.scale=(r-l)/w - p.x=l - end - end - end - if not next(pdfshapes) then - report_svg("there are no converted shapes, fix your setup") - end - statistics.stoptiming() - if statistics.elapsedseconds then - report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") - end - end - return pdfshapes - end -end -local function initializesvg(tfmdata,kind,value) - if value and otf.svgenabled then - local svg=tfmdata.properties.svg - local hash=svg and svg.hash - local timestamp=svg and svg.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then - local svgfile=containers.read(otf.svgcache,hash) - local svgshapes=svgfile and svgfile.svgshapes - pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"svg") - return true - end -end -otfregister { - name="svg", - description="svg glyphs", - manipulators={ - base=initializesvg, - node=initializesvg, - } -} -local otfpng=otf.png or {} -otf.png=otfpng -otf.pngenabled=true -do - local report_png=logs.reporter("fonts","png conversion") - local loaddata=io.loaddata - local savedata=io.savedata - local remove=os.remove - local runner=sandbox and sandbox.registerrunner { - name="otfpng", - program="gm", - template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", - } - if not runner then - runner=function() - return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") - end - end - function otfpng.topdf(pngshapes) - local pdfshapes={} - local pngfile="temp-otf-png-shape.png" - local pdffile="temp-otf-png-shape.pdf" - local nofdone=0 - local indices=sortedkeys(pngshapes) - local nofindices=#indices - report_png("processing %i png containers",nofindices) - statistics.starttiming() - for i=1,nofindices do - local index=indices[i] - local entry=pngshapes[index] - local data=entry.data - local x=entry.x - local y=entry.y - savedata(pngfile,data) - runner() - pdfshapes[index]={ - x=x~=0 and x or nil, - y=y~=0 and y or nil, - data=loaddata(pdffile), - } - nofdone=nofdone+1 - if nofdone%100==0 then - report_png("%i shapes processed",nofdone) - end - end - report_png("processing %i pdf results",nofindices) - remove(pngfile) - remove(pdffile) - statistics.stoptiming() - if statistics.elapsedseconds then - report_png("png conversion time %s",statistics.elapsedseconds() or "-") - end - return pdfshapes - end -end -local function initializepng(tfmdata,kind,value) - if value and otf.pngenabled then - local png=tfmdata.properties.png - local hash=png and png.hash - local timestamp=png and png.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then - local pngfile=containers.read(otf.pngcache,hash) - local pngshapes=pngfile and pngfile.pngshapes - pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"png") - return true - end -end -otfregister { - name="sbix", - description="sbix glyphs", - manipulators={ - base=initializepng, - node=initializepng, - } -} -otfregister { - name="cblc", - description="cblc glyphs", - manipulators={ - base=initializepng, - node=initializepng, - } -} -if context then - local function initializecolor(tfmdata,kind,value) - if value=="auto" then - return - initializeoverlay(tfmdata,kind,value) or - initializesvg(tfmdata,kind,value) or - initializepng(tfmdata,kind,value) - elseif value=="overlay" then - return initializeoverlay(tfmdata,kind,value) - elseif value=="svg" then - return initializesvg(tfmdata,kind,value) - elseif value=="png" or value=="bitmap" then - return initializepng(tfmdata,kind,value) - else - end - end - otfregister { - name="color", - description="color glyphs", - manipulators={ - base=initializecolor, - node=initializecolor, - } - } -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- - -if not modules then modules={} end modules ['font-otc']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash -local type,next,tonumber=type,next,tonumber -local lpegmatch=lpeg.match -local utfbyte,utflen=utf.byte,utf.len -local sortedhash=table.sortedhash -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local setmetatableindex=table.setmetatableindex -local fonthelpers=fonts.helpers -local checkmerge=fonthelpers.checkmerge -local checkflags=fonthelpers.checkflags -local checksteps=fonthelpers.checksteps -local normalized={ - substitution="substitution", - single="substitution", - ligature="ligature", - alternate="alternate", - multiple="multiple", - kern="kern", - pair="pair", - single="single", - chainsubstitution="chainsubstitution", - chainposition="chainposition", -} -local types={ - substitution="gsub_single", - ligature="gsub_ligature", - alternate="gsub_alternate", - multiple="gsub_multiple", - kern="gpos_pair", - pair="gpos_pair", - single="gpos_single", - chainsubstitution="gsub_contextchain", - chainposition="gpos_contextchain", -} -local names={ - gsub_single="gsub", - gsub_multiple="gsub", - gsub_alternate="gsub", - gsub_ligature="gsub", - gsub_context="gsub", - gsub_contextchain="gsub", - gsub_reversecontextchain="gsub", - gpos_single="gpos", - gpos_pair="gpos", - gpos_cursive="gpos", - gpos_mark2base="gpos", - gpos_mark2ligature="gpos", - gpos_mark2mark="gpos", - gpos_context="gpos", - gpos_contextchain="gpos", -} -setmetatableindex(types,function(t,k) t[k]=k return k end) -local everywhere={ ["*"]={ ["*"]=true } } -local noflags={ false,false,false,false } -local function getrange(sequences,category) - local count=#sequences - local first=nil - local last=nil - for i=1,count do - local t=sequences[i].type - if t and names[t]==category then - if not first then - first=i - end - last=i - end - end - return first or 1,last or count -end -local function validspecification(specification,name) - local dataset=specification.dataset - if dataset then - elseif specification[1] then - dataset=specification - specification={ dataset=dataset } - else - dataset={ { data=specification.data } } - specification.data=nil - specification.dataset=dataset - end - local first=dataset[1] - if first then - first=first.data - end - if not first then - report_otf("invalid feature specification, no dataset") - return - end - if type(name)~="string" then - name=specification.name or first.name - end - if type(name)~="string" then - report_otf("invalid feature specification, no name") - return - end - local n=#dataset - if n>0 then - for i=1,n do - setmetatableindex(dataset[i],specification) - end - return specification,name - end -end -local function addfeature(data,feature,specifications) - if not specifications then - report_otf("missing specification") - return - end - local descriptions=data.descriptions - local resources=data.resources - local features=resources.features - local sequences=resources.sequences - if not features or not sequences then - report_otf("missing specification") - return - end - local alreadydone=resources.alreadydone - if not alreadydone then - alreadydone={} - resources.alreadydone=alreadydone - end - if alreadydone[specifications] then - return - else - alreadydone[specifications]=true - end - local fontfeatures=resources.features or everywhere - local unicodes=resources.unicodes - local splitter=lpeg.splitter(" ",unicodes) - local done=0 - local skip=0 - local aglunicodes=false - local privateslot=fonthelpers.privateslot - local specifications=validspecification(specifications,feature) - if not specifications then - return - end - local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1) - local function tounicode(code) - if not code then - return - end - if type(code)=="number" then - return code - end - local u=unicodes[code] - if u then - return u - end - if utflen(code)==1 then - u=utfbyte(code) - if u then - return u - end - end - if privateslot then - u=privateslot(code) - if u then - return u - end - end - local u=lpegmatch(p,code) - if u then - return u - end - if not aglunicodes then - aglunicodes=fonts.encodings.agl.unicodes - end - local u=aglunicodes[code] - if u then - return u - end - end - local coverup=otf.coverup - local coveractions=coverup.actions - local stepkey=coverup.stepkey - local register=coverup.register - local function prepare_substitution(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(replacement)=="table" then - replacement=replacement[1] - end - replacement=tounicode(replacement) - if replacement and (nocheck or descriptions[replacement]) then - cover(coverage,unicode,replacement) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_alternate(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r={} - for i=1,#replacement do - local u=tounicode(replacement[i]) - r[i]=(nocheck or descriptions[u]) and u or unicode - end - cover(coverage,unicode,r) - done=done+1 - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_multiple(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r={} - local n=0 - for i=1,#replacement do - local u=tounicode(replacement[i]) - if nocheck or descriptions[u] then - n=n+1 - r[n]=u - end - end - if n>0 then - cover(coverage,unicode,r) - done=done+1 - else - skip=skip+1 - end - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function prepare_ligature(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,ligature in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(ligature)=="string" then - ligature={ lpegmatch(splitter,ligature) } - end - local present=true - for i=1,#ligature do - local l=ligature[i] - local u=tounicode(l) - if nocheck or descriptions[u] then - ligature[i]=u - else - present=false - break - end - end - if present then - cover(coverage,unicode,ligature) - done=done+1 - else - skip=skip+1 - end - end - end - return coverage - end - local function resetspacekerns() - data.properties.hasspacekerns=true - data.resources .spacekerns=nil - end - local function prepare_kern(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - local isspace=false - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end - return coverage - end - local function prepare_pair(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - if cover then - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end - else - report_otf("unknown cover type %a",featuretype) - end - return coverage - end - local prepare_single=prepare_pair - local function prepare_chain(list,featuretype,sublookups) - local rules=list.rules - local coverage={} - if rules then - local rulehash={} - local rulesize=0 - local lookuptype=types[featuretype] - for nofrules=1,#rules do - local rule=rules[nofrules] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups and sublookups then - for k,v in sortedhash(lookups) do - local t=type(v) - if t=="table" then - for i=1,#v do - local vi=v[i] - if type(vi)~="table" then - v[i]={ vi } - end - end - elseif t=="number" then - local lookup=sublookups[v] - if lookup then - lookups[k]={ lookup } - if not subtype then - subtype=lookup.type - end - elseif v==0 then - lookups[k]={ { type="gsub_remove" } } - else - lookups[k]=false - end - else - lookups[k]=false - end - end - end - if nofsequences>0 then - local hashed={} - for i=1,nofsequences do - local t={} - local s=sequence[i] - for i=1,#s do - local u=tounicode(s[i]) - if u then - t[u]=true - end - end - hashed[i]=t - end - sequence=hashed - rulesize=rulesize+1 - rulehash[rulesize]={ - nofrules, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - for unic in sortedhash(sequence[start]) do - local cu=coverage[unic] - if not cu then - coverage[unic]=rulehash - end - end - sequence.n=nofsequences - end - end - rulehash.n=rulesize - end - return coverage - end - local dataset=specifications.dataset - local function report(name,category,position,first,last,sequences) - report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", - name,category,position,first,last,1,#sequences) - end - local function inject(specification,sequences,sequence,first,last,category,name) - local position=specification.position or false - if not position then - position=specification.prepend - if position==true then - if trace_loading then - report(name,category,first,first,last,sequences) - end - insert(sequences,first,sequence) - return - end - end - if not position then - position=specification.append - if position==true then - if trace_loading then - report(name,category,last+1,first,last,sequences) - end - insert(sequences,last+1,sequence) - return - end - end - local kind=type(position) - if kind=="string" then - local index=false - for i=first,last do - local s=sequences[i] - local f=s.features - if f then - for k in sortedhash(f) do - if k==position then - index=i - break - end - end - if index then - break - end - end - end - if index then - position=index - else - position=last+1 - end - elseif kind=="number" then - if position<0 then - position=last-position+1 - end - if position>last then - position=last+1 - elseif position0 then - for k,v in next,askedfeatures do - if v[1] then - askedfeatures[k]=tohash(v) - end - end - if featureflags[1] then featureflags[1]="mark" end - if featureflags[2] then featureflags[2]="ligature" end - if featureflags[3] then featureflags[3]="base" end - local steptype=types[featuretype] - local sequence={ - chain=featurechain, - features={ [feature]=askedfeatures }, - flags=featureflags, - name=feature, - order=featureorder, - [stepkey]=steps, - nofsteps=nofsteps, - type=steptype, - } - checkflags(sequence,resources) - checkmerge(sequence) - checksteps(sequence) - local first,last=getrange(sequences,category) - inject(specification,sequences,sequence,first,last,category,feature) - local features=fontfeatures[category] - if not features then - features={} - fontfeatures[category]=features - end - local k=features[feature] - if not k then - k={} - features[feature]=k - end - for script,languages in next,askedfeatures do - local kk=k[script] - if not kk then - kk={} - k[script]=kk - end - for language,value in next,languages do - kk[language]=value - end - end - end - end - end - if trace_loading then - report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) - end -end -otf.enhancers.addfeature=addfeature -local extrafeatures={} -local knownfeatures={} -function otf.addfeature(name,specification) - if type(name)=="table" then - specification=name - end - if type(specification)~="table" then - report_otf("invalid feature specification, no valid table") - return - end - specification,name=validspecification(specification,name) - if name and specification then - local slot=knownfeatures[name] - if not slot then - slot=#extrafeatures+1 - knownfeatures[name]=slot - elseif specification.overload==false then - slot=#extrafeatures+1 - knownfeatures[name]=slot - else - end - specification.name=name - extrafeatures[slot]=specification - end -end -local function enhance(data,filename,raw) - for slot=1,#extrafeatures do - local specification=extrafeatures[slot] - addfeature(data,specification.name,specification) - end -end -otf.enhancers.enhance=enhance -otf.enhancers.register("check extra features",enhance) - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr” 7a9ece7bf3e36b5f0adf295a9a2a2989] --- - -if not modules then modules={} end modules ['font-onr']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers -local next,type,tonumber,rawset=next,type,tonumber,rawset -local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find -local char,byte,sub=string.char,string.byte,string.sub -local abs=math.abs -local bxor,rshift=bit32.bxor,bit32.rshift -local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc -local lpegmatch,patterns=lpeg.match,lpeg.patterns -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) -local report_afm=logs.reporter("fonts","afm loading") -local report_pfb=logs.reporter("fonts","pfb loading") -local handlers=fonts.handlers -local afm=handlers.afm or {} -handlers.afm=afm -local readers=afm.readers or {} -afm.readers=readers -afm.version=1.513 -local get_indexes,get_shapes -do - local decrypt - do - local r,c1,c2,n=0,0,0,0 - local function step(c) - local cipher=byte(c) - local plain=bxor(cipher,rshift(r,8)) - r=((cipher+r)*c1+c2)%65536 - return char(plain) - end - decrypt=function(binary,initial,seed) - r,c1,c2,n=initial,52845,22719,seed - binary=gsub(binary,".",step) - return sub(binary,n+1) - end - end - local charstrings=P("/CharStrings") - local subroutines=P("/Subrs") - local encoding=P("/Encoding") - local dup=P("dup") - local put=P("put") - local array=P("array") - local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) - local digits=R("09")^1 - local cardinal=digits/tonumber - local spaces=P(" ")^1 - local spacing=patterns.whitespace^0 - local routines,vector,chars,n,m - local initialize=function(str,position,size) - n=0 - m=size - return position+1 - end - local setroutine=function(str,position,index,size,filename) - if routines[index] then - return false - end - local forward=position+size - local stream=decrypt(sub(str,position+1,forward),4330,4) - routines[index]={ byte(stream,1,#stream) } - n=n+1 - if n>=m then - return #str - end - return forward+1 - end - local setvector=function(str,position,name,size,filename) - local forward=position+tonumber(size) - if n>=m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - return forward - else - return #str - end - end - local setshapes=function(str,position,name,size,filename) - local forward=position+tonumber(size) - local stream=sub(str,position+1,forward) - if n>m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - chars [n]=decrypt(stream,4330,4) - return forward - else - return #str - end - end - local p_rd=spacing*(P("RD")+P("-|")) - local p_np=spacing*(P("NP")+P("|")) - local p_nd=spacing*(P("ND")+P("|")) - local p_filterroutines= - (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1 - local p_filtershapes= - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 - local p_filternames=Ct ( - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 - ) - local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( - Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 -,rawset) - local key=spacing*P("/")*R("az","AZ") - local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") } - local num=spacing*(R("09")+S("+-."))^1/tonumber - local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}")) - local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false)) - local nam=spacing*P("/")*Cs(R("az","AZ")^1) - local p_filtermetadata=( - P("/")*Carg(1)*(( - C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr - ) )/function(t,k,v) t[lower(k)]=v end+P(1) - )^0*Carg(1) - local function loadpfbvector(filename,shapestoo,streams) - local data=io.loaddata(resolvers.findfile(filename)) - if not data then - report_pfb("no data in %a",filename) - return - end - if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then - report_pfb("no font in %a",filename) - return - end - local ascii,binary=match(data,"(.*)eexec%s+......(.*)") - if not binary then - report_pfb("no binary data in %a",filename) - return - end - binary=decrypt(binary,55665,4) - local names={} - local encoding=lpegmatch(p_filterencoding,ascii) - local metadata=lpegmatch(p_filtermetadata,ascii,1,{}) - local glyphs={} - routines,vector,chars={},{},{} - if shapestoo or streams then - lpegmatch(p_filterroutines,binary,1,filename) - lpegmatch(p_filtershapes,binary,1,filename) - local data={ - dictionaries={ - { - charstrings=chars, - charset=vector, - subroutines=routines, - } - }, - } - fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true) - else - lpegmatch(p_filternames,binary,1,filename) - end - names=vector - routines,vector,chars=nil,nil,nil - return names,encoding,glyphs,metadata - end - local pfb=handlers.pfb or {} - handlers.pfb=pfb - pfb.loadvector=loadpfbvector - get_indexes=function(data,pfbname) - local vector=loadpfbvector(pfbname) - if vector then - local characters=data.characters - if trace_loading then - report_afm("getting index data from %a",pfbname) - end - for index=0,#vector do - local name=vector[index] - local char=characters[name] - if char then - if trace_indexing then - report_afm("glyph %a has index %a",name,index) - end - char.index=index - else - if trace_indexing then - report_afm("glyph %a has index %a but no data",name,index) - end - end - end - end - end - get_shapes=function(pfbname) - local vector,encoding,glyphs=loadpfbvector(pfbname,true) - return glyphs - end -end -local spacer=patterns.spacer -local whitespace=patterns.whitespace -local lineend=patterns.newline -local spacing=spacer^0 -local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber -local name=spacing*C((1-whitespace)^1) -local words=spacing*((1-lineend)^1/strip) -local rest=(1-lineend)^0 -local fontdata=Carg(1) -local semicolon=spacing*P(";") -local plus=spacing*P("plus")*number -local minus=spacing*P("minus")*number -local function addkernpair(data,one,two,value) - local chr=data.characters[one] - if chr then - local kerns=chr.kerns - if kerns then - kerns[two]=tonumber(value) - else - chr.kerns={ [two]=tonumber(value) } - end - end -end -local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair -local chr=false -local ind=0 -local function start(data,version) - data.metadata.afmversion=version - ind=0 - chr={} -end -local function stop() - ind=0 - chr=false -end -local function setindex(i) - if i<0 then - ind=ind+1 - else - ind=i - end - chr={ - index=ind - } -end -local function setwidth(width) - chr.width=width -end -local function setname(data,name) - data.characters[name]=chr -end -local function setboundingbox(boundingbox) - chr.boundingbox=boundingbox -end -local function setligature(plus,becomes) - local ligatures=chr.ligatures - if ligatures then - ligatures[plus]=becomes - else - chr.ligatures={ [plus]=becomes } - end -end -local p_charmetric=(( - P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature - )*semicolon )^1 -local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics") -local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) -local function set_1(data,key,a) data.metadata[lower(key)]=a end -local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end -local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end -local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value) - data.metadata[key]=value - end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) - data.metadata[key]=value - end+fontdata*P("IsFixedPitch")*name/function(data,pitch) - data.metadata.monospaced=toboolean(pitch,true) - end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) - data.metadata.boundingbox=boundingbox - end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) - data.metadata[key]=value - end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 -+(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 -+(fontdata*C("CHECKSUM")*number*words*rest)/set_1 -+(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 -+(fontdata*C("QUAD")*number*rest)/set_1 -+(fontdata*C("EXTRASPACE")*number*rest)/set_1 -+(fontdata*C("NUM")*number*number*number*rest)/set_3 -+(fontdata*C("DENOM")*number*number*rest)/set_2 -+(fontdata*C("SUP")*number*number*number*rest)/set_3 -+(fontdata*C("SUB")*number*number*rest)/set_2 -+(fontdata*C("SUPDROP")*number*rest)/set_1 -+(fontdata*C("SUBDROP")*number*rest)/set_1 -+(fontdata*C("DELIM")*number*number*rest)/set_2 -+(fontdata*C("AXISHEIGHT")*number*rest)/set_1 - ) -local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) -local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) -local function read(filename,parser) - local afmblob=io.loaddata(filename) - if afmblob then - local data={ - resources={ - filename=resolvers.unresolve(filename), - version=afm.version, - creator="context mkiv", - }, - properties={ - hasitalics=false, - }, - goodies={}, - metadata={ - filename=file.removesuffix(file.basename(filename)) - }, - characters={ - }, - descriptions={ - }, - } - if trace_loading then - report_afm("parsing afm file %a",filename) - end - lpegmatch(parser,afmblob,1,data) - return data - else - if trace_loading then - report_afm("no valid afm file %a",filename) - end - return nil - end -end -function readers.loadfont(afmname,pfbname) - local data=read(resolvers.findfile(afmname),fullparser) - if data then - if not pfbname or pfbname=="" then - pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) - end - if pfbname and pfbname~="" then - data.resources.filename=resolvers.unresolve(pfbname) - get_indexes(data,pfbname) - return data - else - report_afm("no pfb file for %a",afmname) - end - end -end -function readers.loadshapes(filename) - local fullname=resolvers.findfile(filename) or "" - if fullname=="" then - return { - filename="not found: "..filename, - glyphs={} - } - else - return { - filename=fullname, - format="opentype", - glyphs=get_shapes(fullname) or {}, - units=1000, - } - end -end -function readers.getinfo(filename) - local data=read(resolvers.findfile(filename),infoparser) - if data then - return data.metadata - end -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one” 1402ae8e4e96186c848fa2742388fb24] --- - -if not modules then modules={} end modules ['font-one']={ - version=1.001, - optimize=true, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers -local next,type,tonumber,rawget=next,type,tonumber,rawget -local match,gsub=string.match,string.gsub -local abs=math.abs -local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg -local lpegmatch,patterns=lpeg.match,lpeg.patterns -local sortedhash=table.sortedhash -local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local report_afm=logs.reporter("fonts","afm loading") -local setmetatableindex=table.setmetatableindex -local derivetable=table.derive -local findbinfile=resolvers.findbinfile -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local definers=fonts.definers -local readers=fonts.readers -local constructors=fonts.constructors -local afm=constructors.handlers.afm -local pfb=constructors.handlers.pfb -local otf=fonts.handlers.otf -local otfreaders=otf.readers -local otfenhancers=otf.enhancers -local afmfeatures=constructors.features.afm -local registerafmfeature=afmfeatures.register -local afmenhancers=constructors.enhancers.afm -local registerafmenhancer=afmenhancers.register -afm.version=1.513 -afm.cache=containers.define("fonts","one",afm.version,true) -afm.autoprefixed=true -afm.helpdata={} -afm.syncspace=true -local overloads=fonts.mappings.overloads -local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes -function afm.load(filename) - filename=resolvers.findfile(filename,'afm') or "" - if filename~="" and not fonts.names.ignoredfile(filename) then - local name=file.removesuffix(file.basename(filename)) - local data=containers.read(afm.cache,name) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local pfbfile=file.replacesuffix(name,"pfb") - local pfbname=resolvers.findfile(pfbfile,"pfb") or "" - if pfbname=="" then - pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" - end - local pfbsize=0 - local pfbtime=0 - if pfbname~="" then - local attr=lfs.attributes(pfbname) - pfbsize=attr.size or 0 - pfbtime=attr.modification or 0 - end - if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then - report_afm("reading %a",filename) - data=afm.readers.loadfont(filename,pfbname) - if data then - afmenhancers.apply(data,filename) - fonts.mappings.addtounicode(data,filename) - otfreaders.stripredundant(data) - otfreaders.pack(data) - data.size=size - data.time=time - data.pfbsize=pfbsize - data.pfbtime=pfbtime - report_afm("saving %a in cache",name) - data=containers.write(afm.cache,name,data) - data=containers.read(afm.cache,name) - end - end - if data then - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - end - return data - end -end -local uparser=fonts.mappings.makenameparser() -local function enhance_unify_names(data,filename) - local unicodevector=fonts.encodings.agl.unicodes - local unicodes={} - local names={} - local private=data.private or privateoffset - local descriptions=data.descriptions - for name,blob in sortedhash(data.characters) do - local code=unicodevector[name] - if not code then - code=lpegmatch(uparser,name) - if type(code)~="number" then - code=private - private=private+1 - report_afm("assigning private slot %U for unknown glyph name %a",code,name) - end - end - local index=blob.index - unicodes[name]=code - names[name]=index - blob.name=name - descriptions[code]={ - boundingbox=blob.boundingbox, - width=blob.width, - kerns=blob.kerns, - index=index, - name=name, - } - end - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local krn={} - for name,kern in next,kerns do - local unicode=unicodes[name] - if unicode then - krn[unicode]=kern - else - end - end - description.kerns=krn - end - end - data.characters=nil - data.private=private - local resources=data.resources - local filename=resources.filename or file.removesuffix(file.basename(filename)) - resources.filename=resolvers.unresolve(filename) - resources.unicodes=unicodes - resources.marks={} -end -local everywhere={ ["*"]={ ["*"]=true } } -local noflags={ false,false,false,false } -local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local extrakerns=setmetatableindex("table") - for u,c in next,data.descriptions do - local l=c.ligatures - local k=c.kerns - local e=c.extrakerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - if e then - extrakerns[u]=e - for u,v in next,e do - e[u]=v - end - c.extrakerns=nil - end - end - local features={ - gpos={}, - gsub={}, - } - local sequences={ - } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } - end - if next(extrakerns) then - features.gpos.extrakerns=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - extrakerns=everywhere, - }, - flags=noflags, - name="p_s_1", - nofsteps=1, - order={ "extrakerns" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=extrakerns, - }, - }, - } - end - data.resources.features=features - data.resources.sequences=sequences -end -local function enhance_fix_names(data) - for k,v in next,data.descriptions do - local n=v.name - local r=overloads[n] - if r then - local name=r.name - if trace_indexing then - report_afm("renaming characters %a to %a",n,name) - end - v.name=name - v.unicode=r.unicode - end - end -end -local addthem=function(rawdata,ligatures) - if ligatures then - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - for ligname,ligdata in next,ligatures do - local one=descriptions[unicodes[ligname]] - if one then - for _,pair in next,ligdata do - local two=unicodes[pair[1]] - local three=unicodes[pair[2]] - if two and three then - local ol=one.ligatures - if ol then - if not ol[two] then - ol[two]=three - end - else - one.ligatures={ [two]=three } - end - end - end - end - end - end -end -local function enhance_add_ligatures(rawdata) - addthem(rawdata,afm.helpdata.ligatures) -end -local function enhance_add_extra_kerns(rawdata) - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - local function do_it_left(what) - if what then - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local extrakerns - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local ks=kerns[simple] - if ks and not kerns[complex] then - if extrakerns then - extrakerns[complex]=ks - else - extrakerns={ [complex]=ks } - end - end - end - end - if extrakerns then - description.extrakerns=extrakerns - end - end - end - end - end - local function do_it_copy(what) - if what then - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local complexdescription=descriptions[complex] - if complexdescription then - local simpledescription=descriptions[complex] - if simpledescription then - local extrakerns - local kerns=simpledescription.kerns - if kerns then - for unicode,kern in next,kerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - local extrakerns=simpledescription.extrakerns - if extrakerns then - for unicode,kern in next,extrakerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - if extrakerns then - complexdescription.extrakerns=extrakerns - end - end - end - end - end - end - end - do_it_left(afm.helpdata.leftkerned) - do_it_left(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.rightkerned) -end -local function adddimensions(data) - if data then - for unicode,description in next,data.descriptions do - local bb=description.boundingbox - if bb then - local ht=bb[4] - local dp=-bb[2] - if ht==0 or ht<0 then - else - description.height=ht - end - if dp==0 or dp<0 then - else - description.depth=dp - end - end - end - end -end -local function copytotfm(data) - if data and data.descriptions then - local metadata=data.metadata - local resources=data.resources - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local unicodes=resources.unicodes - for unicode,description in next,data.descriptions do - characters[unicode]={} - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname or metadata.fullname - local fullname=metadata.fullname or metadata.fontname - local endash=0x2013 - local emdash=0x2014 - local space=0x0020 - local spacer="space" - local spaceunits=500 - local monospaced=metadata.monospaced - local charwidth=metadata.charwidth - local italicangle=metadata.italicangle - local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight - properties.monospaced=monospaced - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - local d_endash=descriptions[endash] - local d_emdash=descriptions[emdash] - local d_space=descriptions[space] - if not d_space or d_space==0 then - d_space=d_endash - end - if d_space then - spaceunits,spacer=d_space.width or 0,"space" - end - if properties.monospaced then - if spaceunits==0 and d_emdash then - spaceunits,spacer=d_emdash.width or 0,"emdash" - end - else - if spaceunits==0 and d_endash then - spaceunits,spacer=d_emdash.width or 0,"endash" - end - end - if spaceunits==0 and charwidth then - spaceunits,spacer=charwidth or 0,"charwidth" - end - if spaceunits==0 then - spaceunits=tonumber(spaceunits) or 500 - end - if spaceunits==0 then - spaceunits=500 - end - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=500 - parameters.space_shrink=333 - parameters.x_height=400 - parameters.quad=1000 - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif afm.syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight - else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end - end - if metadata.sup then - local dummy={ 0,0,0 } - parameters[ 1]=metadata.designsize or 0 - parameters[ 2]=metadata.checksum or 0 - parameters[ 3], - parameters[ 4], - parameters[ 5]=unpack(metadata.space or dummy) - parameters[ 6]=metadata.quad or 0 - parameters[ 7]=metadata.extraspace or 0 - parameters[ 8], - parameters[ 9], - parameters[10]=unpack(metadata.num or dummy) - parameters[11], - parameters[12]=unpack(metadata.denom or dummy) - parameters[13], - parameters[14], - parameters[15]=unpack(metadata.sup or dummy) - parameters[16], - parameters[17]=unpack(metadata.sub or dummy) - parameters[18]=metadata.supdrop or 0 - parameters[19]=metadata.subdrop or 0 - parameters[20], - parameters[21]=unpack(metadata.delim or dummy) - parameters[22]=metadata.axisheight or 0 - end - parameters.designsize=(metadata.designsize or 10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=1000 - properties.spacer=spacer - properties.encodingbytes=2 - properties.format=fonts.formats[filename] or "type1" - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=fullname - properties.name=filename or fullname or fontname - properties.private=properties.private or data.private or privateoffset - if next(characters) then - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - resources=resources, - properties=properties, - goodies=goodies, - } - end - end - return nil -end -function afm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) - if okay then - return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) - else - return {} - end -end -local function addtables(data) - local resources=data.resources - local lookuptags=resources.lookuptags - local unicodes=resources.unicodes - if not lookuptags then - lookuptags={} - resources.lookuptags=lookuptags - end - setmetatableindex(lookuptags,function(t,k) - local v=type(k)=="number" and ("lookup "..k) or k - t[k]=v - return v - end) - if not unicodes then - unicodes={} - resources.unicodes=unicodes - setmetatableindex(unicodes,function(t,k) - setmetatableindex(unicodes,nil) - for u,d in next,data.descriptions do - local n=d.name - if n then - t[n]=u - end - end - return rawget(t,k) - end) - end - constructors.addcoreunicodes(unicodes) -end -local function afmtotfm(specification) - local afmname=specification.filename or specification.name - if specification.forced=="afm" or specification.format=="afm" then - if trace_loading then - report_afm("forcing afm format for %a",afmname) - end - else - local tfmname=findbinfile(afmname,"ofm") or "" - if tfmname~="" then - if trace_loading then - report_afm("fallback from afm to tfm for %a",afmname) - end - return - end - end - if afmname~="" then - local features=constructors.checkedfeatures("afm",specification.features.normal) - specification.features.normal=features - constructors.hashinstance(specification,true) - specification=definers.resolve(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - local rawdata=afm.load(afmname) - if rawdata and next(rawdata) then - addtables(rawdata) - adddimensions(rawdata) - tfmdata=copytotfm(rawdata) - if tfmdata and next(tfmdata) then - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=afm.setfeatures(tfmdata,features) - end - elseif trace_loading then - report_afm("no (valid) afm file found with name %a",afmname) - end - tfmdata=containers.write(constructors.cache,cache_id,tfmdata) - end - return tfmdata - end -end -local function read_from_afm(specification) - local tfmdata=afmtotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) - fonts.loggers.register(tfmdata,'afm',specification) - end - return tfmdata -end -registerafmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } -} -registerafmfeature { - name="features", - description="features", - default=true, - initializers={ - node=otf.nodemodeinitializer, - base=otf.basemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } -} -fonts.formats.afm="type1" -fonts.formats.pfb="type1" -local function check_afm(specification,fullname) - local foundname=findbinfile(fullname,'afm') or "" - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"afm") or "" - end - if fullname and foundname=="" and afm.autoprefixed then - local encoding,shortname=match(fullname,"^(.-)%-(.*)$") - if encoding and shortname and fonts.encodings.known[encoding] then - shortname=findbinfile(shortname,'afm') or "" - if shortname~="" then - foundname=shortname - if trace_defining then - report_afm("stripping encoding prefix from filename %a",afmname) - end - end - end - end - if foundname~="" then - specification.filename=foundname - specification.format="afm" - return read_from_afm(specification) - end -end -function readers.afm(specification,method) - local fullname=specification.filename or "" - local tfmdata=nil - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - tfmdata=check_afm(specification,specification.name.."."..forced) - end - if not tfmdata then - local check_tfm=readers.check_tfm - method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" - if method=="tfm" then - tfmdata=check_tfm(specification,specification.name) - elseif method=="afm" then - tfmdata=check_afm(specification,specification.name) - elseif method=="tfm or afm" then - tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) - else - tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) - end - end - else - tfmdata=check_afm(specification,fullname) - end - return tfmdata -end -function readers.pfb(specification,method) - local original=specification.specification - if trace_defining then - report_afm("using afm reader for %a",original) - end - specification.forced="afm" - local function swap(name) - local value=specification[swap] - if value then - specification[swap]=gsub("%.pfb",".afm",1) - end - end - swap("filename") - swap("fullname") - swap("forcedname") - swap("specification") - return readers.afm(specification,method) -end -registerafmenhancer("unify names",enhance_unify_names) -registerafmenhancer("add ligatures",enhance_add_ligatures) -registerafmenhancer("add extra kerns",enhance_add_extra_kerns) -registerafmenhancer("normalize features",enhance_normalize_features) -registerafmenhancer("check extra features",otfenhancers.enhance) -registerafmenhancer("fix names",enhance_fix_names) - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- - -if not modules then modules={} end modules ['font-afk']={ - version=1.001, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", - dataonly=true, -} -local allocate=utilities.storage.allocate -fonts.handlers.afm.helpdata={ - ligatures=allocate { - ['f']={ - { 'f','ff' }, - { 'i','fi' }, - { 'l','fl' }, - }, - ['ff']={ - { 'i','ffi' } - }, - ['fi']={ - { 'i','fii' } - }, - ['fl']={ - { 'i','fli' } - }, - ['s']={ - { 't','st' } - }, - ['i']={ - { 'j','ij' } - }, - }, - texligatures=allocate { - ['quoteleft']={ - { 'quoteleft','quotedblleft' } - }, - ['quoteright']={ - { 'quoteright','quotedblright' } - }, - ['hyphen']={ - { 'hyphen','endash' } - }, - ['endash']={ - { 'hyphen','emdash' } - } - }, - leftkerned=allocate { - AEligature="A",aeligature="a", - OEligature="O",oeligature="o", - IJligature="I",ijligature="i", - AE="A",ae="a", - OE="O",oe="o", - IJ="I",ij="i", - Ssharp="S",ssharp="s", - }, - rightkerned=allocate { - AEligature="E",aeligature="e", - OEligature="E",oeligature="e", - IJligature="J",ijligature="j", - AE="E",ae="e", - OE="E",oe="e", - IJ="J",ij="j", - Ssharp="S",ssharp="s", - }, - bothkerned=allocate { - Acircumflex="A",acircumflex="a", - Ccircumflex="C",ccircumflex="c", - Ecircumflex="E",ecircumflex="e", - Gcircumflex="G",gcircumflex="g", - Hcircumflex="H",hcircumflex="h", - Icircumflex="I",icircumflex="i", - Jcircumflex="J",jcircumflex="j", - Ocircumflex="O",ocircumflex="o", - Scircumflex="S",scircumflex="s", - Ucircumflex="U",ucircumflex="u", - Wcircumflex="W",wcircumflex="w", - Ycircumflex="Y",ycircumflex="y", - Agrave="A",agrave="a", - Egrave="E",egrave="e", - Igrave="I",igrave="i", - Ograve="O",ograve="o", - Ugrave="U",ugrave="u", - Ygrave="Y",ygrave="y", - Atilde="A",atilde="a", - Itilde="I",itilde="i", - Otilde="O",otilde="o", - Utilde="U",utilde="u", - Ntilde="N",ntilde="n", - Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", - Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", - Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", - Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", - Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", - Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", - Aacute="A",aacute="a", - Cacute="C",cacute="c", - Eacute="E",eacute="e", - Iacute="I",iacute="i", - Lacute="L",lacute="l", - Nacute="N",nacute="n", - Oacute="O",oacute="o", - Racute="R",racute="r", - Sacute="S",sacute="s", - Uacute="U",uacute="u", - Yacute="Y",yacute="y", - Zacute="Z",zacute="z", - Dstroke="D",dstroke="d", - Hstroke="H",hstroke="h", - Tstroke="T",tstroke="t", - Cdotaccent="C",cdotaccent="c", - Edotaccent="E",edotaccent="e", - Gdotaccent="G",gdotaccent="g", - Idotaccent="I",idotaccent="i", - Zdotaccent="Z",zdotaccent="z", - Amacron="A",amacron="a", - Emacron="E",emacron="e", - Imacron="I",imacron="i", - Omacron="O",omacron="o", - Umacron="U",umacron="u", - Ccedilla="C",ccedilla="c", - Kcedilla="K",kcedilla="k", - Lcedilla="L",lcedilla="l", - Ncedilla="N",ncedilla="n", - Rcedilla="R",rcedilla="r", - Scedilla="S",scedilla="s", - Tcedilla="T",tcedilla="t", - Ohungarumlaut="O",ohungarumlaut="o", - Uhungarumlaut="U",uhungarumlaut="u", - Aogonek="A",aogonek="a", - Eogonek="E",eogonek="e", - Iogonek="I",iogonek="i", - Uogonek="U",uogonek="u", - Aring="A",aring="a", - Uring="U",uring="u", - Abreve="A",abreve="a", - Ebreve="E",ebreve="e", - Gbreve="G",gbreve="g", - Ibreve="I",ibreve="i", - Obreve="O",obreve="o", - Ubreve="U",ubreve="u", - Ccaron="C",ccaron="c", - Dcaron="D",dcaron="d", - Ecaron="E",ecaron="e", - Lcaron="L",lcaron="l", - Ncaron="N",ncaron="n", - Rcaron="R",rcaron="r", - Scaron="S",scaron="s", - Tcaron="T",tcaron="t", - Zcaron="Z",zcaron="z", - dotlessI="I",dotlessi="i", - dotlessJ="J",dotlessj="j", - AEligature="AE",aeligature="ae",AE="AE",ae="ae", - OEligature="OE",oeligature="oe",OE="OE",oe="oe", - IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", - Lstroke="L",lstroke="l",Lslash="L",lslash="l", - Ostroke="O",ostroke="o",Oslash="O",oslash="o", - Ssharp="SS",ssharp="ss", - Aumlaut="A",aumlaut="a", - Eumlaut="E",eumlaut="e", - Iumlaut="I",iumlaut="i", - Oumlaut="O",oumlaut="o", - Uumlaut="U",uumlaut="u", - } -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- - -if not modules then modules={} end modules ['luatex-fonts-tfm']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type=next,type -local match,format=string.match,string.format -local concat,sortedhash=table.concat,table.sortedhash -local idiv=number.idiv -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) -local report_defining=logs.reporter("fonts","defining") -local report_tfm=logs.reporter("fonts","tfm loading") -local findbinfile=resolvers.findbinfile -local setmetatableindex=table.setmetatableindex -local fonts=fonts -local handlers=fonts.handlers -local helpers=fonts.helpers -local readers=fonts.readers -local constructors=fonts.constructors -local encodings=fonts.encodings -local tfm=constructors.handlers.tfm -tfm.version=1.000 -tfm.maxnestingdepth=5 -tfm.maxnestingsize=65536*1024 -local otf=fonts.handlers.otf -local otfenhancers=otf.enhancers -local tfmfeatures=constructors.features.tfm -local registertfmfeature=tfmfeatures.register -local tfmenhancers=constructors.enhancers.tfm -local registertfmenhancer=tfmenhancers.register -local charcommand=helpers.commands.char -constructors.resolvevirtualtoo=false -fonts.formats.tfm="type1" -fonts.formats.ofm="type1" -function tfm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) - if okay then - return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) - else - return {} - end -end -local depth={} -local loadtfm=font.read_tfm -local loadvf=font.read_vf -local function read_from_tfm(specification) - local filename=specification.filename - local size=specification.size - depth[filename]=(depth[filename] or 0)+1 - if trace_defining then - report_defining("loading tfm file %a at size %s",filename,size) - end - local tfmdata=loadtfm(filename,size) - if tfmdata then - local features=specification.features and specification.features.normal or {} - local features=constructors.checkedfeatures("tfm",features) - specification.features.normal=features - local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) - if newtfmdata then - tfmdata=newtfmdata - end - local resources=tfmdata.resources or {} - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - local shared=tfmdata.shared or {} - shared.features=features - shared.resources=resources - properties.name=tfmdata.name - properties.fontname=tfmdata.fontname - properties.psname=tfmdata.psname - properties.fullname=tfmdata.fullname - properties.filename=specification.filename - properties.format=tfmdata.format or fonts.formats.tfm - properties.usedbitmap=tfmdata.usedbitmap - tfmdata.properties=properties - tfmdata.resources=resources - tfmdata.parameters=parameters - tfmdata.shared=shared - shared.rawdata={ resources=resources } - shared.features=features - if newtfmdata then - if not resources.marks then - resources.marks={} - end - if not resources.sequences then - resources.sequences={} - end - if not resources.features then - resources.features={ - gsub={}, - gpos={}, - } - end - if not tfmdata.changed then - tfmdata.changed={} - end - if not tfmdata.descriptions then - tfmdata.descriptions=tfmdata.characters - end - otf.readers.addunicodetable(tfmdata) - tfmenhancers.apply(tfmdata,filename) - constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) - otf.readers.unifymissing(tfmdata) - fonts.mappings.addtounicode(tfmdata,filename) - tfmdata.tounicode=1 - local tounicode=fonts.mappings.tounicode - for unicode,v in next,tfmdata.characters do - local u=v.unicode - if u then - v.tounicode=tounicode(u) - end - end - if tfmdata.usedbitmap then - tfm.addtounicode(tfmdata) - end - end - shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil - if size<0 then - size=idiv(65536*-size,100) - end - parameters.factor=1 - parameters.units=1000 - parameters.size=size - parameters.slant=parameters.slant or parameters[1] or 0 - parameters.space=parameters.space or parameters[2] or 0 - parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 - parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 - parameters.x_height=parameters.x_height or parameters[5] or 0 - parameters.quad=parameters.quad or parameters[6] or 0 - parameters.extra_space=parameters.extra_space or parameters[7] or 0 - constructors.enhanceparameters(parameters) - properties.private=properties.private or tfmdata.private or privateoffset - if newtfmdata then - elseif constructors.resolvevirtualtoo then - fonts.loggers.register(tfmdata,file.suffix(filename),specification) - local vfname=findbinfile(specification.name,'ovf') - if vfname and vfname~="" then - local vfdata=loadvf(vfname,size) - if vfdata then - local chars=tfmdata.characters - for k,v in next,vfdata.characters do - chars[k].commands=v.commands - end - properties.virtualized=true - tfmdata.fonts=vfdata.fonts - tfmdata.type="virtual" - local fontlist=vfdata.fonts - local name=file.nameonly(filename) - for i=1,#fontlist do - local n=fontlist[i].name - local s=fontlist[i].size - local d=depth[filename] - s=constructors.scaled(s,vfdata.designsize) - if d>tfm.maxnestingdepth then - report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) - fontlist[i]={ id=0 } - elseif (d>1) and (s>tfm.maxnestingsize) then - report_defining("virtual font %a exceeds size %s",n,s) - fontlist[i]={ id=0 } - else - local t,id=constructors.readanddefine(n,s) - fontlist[i]={ id=id } - end - end - end - end - end - properties.haskerns=true - properties.hasligatures=true - properties.hasitalics=true - resources.unicodes={} - resources.lookuptags={} - depth[filename]=depth[filename]-1 - return tfmdata - else - depth[filename]=depth[filename]-1 - end -end -local function check_tfm(specification,fullname) - local foundname=findbinfile(fullname,'tfm') or "" - if foundname=="" then - foundname=findbinfile(fullname,'ofm') or "" - end - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"tfm") or "" - end - if foundname~="" then - specification.filename=foundname - specification.format="ofm" - return read_from_tfm(specification) - elseif trace_defining then - report_defining("loading tfm with name %a fails",specification.name) - end -end -readers.check_tfm=check_tfm -function readers.tfm(specification) - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end - end - return check_tfm(specification,fullname) -end -readers.ofm=readers.tfm -do - local outfiles={} - local tfmcache=table.setmetatableindex(function(t,tfmdata) - local id=font.define(tfmdata) - t[tfmdata]=id - return id - end) - local encdone=table.setmetatableindex("table") - function tfm.reencode(tfmdata,specification) - local features=specification.features - if not features then - return - end - local features=features.normal - if not features then - return - end - local tfmfile=file.basename(tfmdata.name) - local encfile=features.reencode - local pfbfile=features.pfbfile - local bitmap=features.bitmap - if not encfile then - return - end - local pfbfile=outfiles[tfmfile] - if pfbfile==nil then - if bitmap then - pfbfile=false - elseif type(pfbfile)~="string" then - pfbfile=tfmfile - end - if type(pfbfile)=="string" then - pfbfile=file.addsuffix(pfbfile,"pfb") - report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) - else - report_tfm("using bitmap shapes for %a",tfmfile) - pfbfile=false - end - outfiles[tfmfile]=pfbfile - end - local encoding=false - local vector=false - if type(pfbfile)=="string" then - local pfb=constructors.handlers.pfb - if pfb and pfb.loadvector then - local v,e=pfb.loadvector(pfbfile) - if v then - vector=v - end - if e then - encoding=e - end - end - end - if type(encfile)=="string" and encfile~="auto" then - encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) - if encoding then - encoding=encoding.vector - end - end - if not encoding then - report_tfm("bad encoding for %a, quitting",tfmfile) - return - end - local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes - local virtualid=tfmcache[tfmdata] - local tfmdata=table.copy(tfmdata) - local characters={} - local originals=tfmdata.characters - local indices={} - local parentfont={ "font",1 } - local private=tfmdata.privateoffset or constructors.privateoffset - local reported=encdone[tfmfile][encfile] - local backmap=vector and table.swapped(vector) - local done={} - for index,name in sortedhash(encoding) do - local unicode=unicoding[name] - local original=originals[index] - if original then - if unicode then - original.unicode=unicode - else - unicode=private - private=private+1 - if not reported then - report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) - end - end - characters[unicode]=original - indices[index]=unicode - original.name=name - if backmap then - original.index=backmap[name] - else - original.commands={ parentfont,charcommand[index] } - original.oindex=index - end - done[name]=true - elseif not done[name] then - report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) - end - end - encdone[tfmfile][encfile]=true - for k,v in next,characters do - local kerns=v.kerns - if kerns then - local t={} - for k,v in next,kerns do - local i=indices[k] - if i then - t[i]=v - end - end - v.kerns=next(t) and t or nil - end - local ligatures=v.ligatures - if ligatures then - local t={} - for k,v in next,ligatures do - local i=indices[k] - if i then - t[i]=v - v.char=indices[v.char] - end - end - v.ligatures=next(t) and t or nil - end - end - tfmdata.fonts={ { id=virtualid } } - tfmdata.characters=characters - tfmdata.fullname=tfmdata.fullname or tfmdata.name - tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) - tfmdata.filename=pfbfile - tfmdata.encodingbytes=2 - tfmdata.format="type1" - tfmdata.tounicode=1 - tfmdata.embedding="subset" - tfmdata.usedbitmap=bitmap and virtualid - tfmdata.private=private - return tfmdata - end -end -do - local template=[[ -/CIDInit /ProcSet findresource begin - 12 dict begin - begincmap - /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def - /CMapName /TeX-bitmap-%s def - /CMapType 2 def - 1 begincodespacerange - <00> - endcodespacerange - %s beginbfchar -%s - endbfchar - endcmap -CMapName currentdict /CMap defineresource pop end -end -end -]] - local flushstreamobject=lpdf and lpdf.flushstreamobject - local setfontattributes=lpdf and lpdf.setfontattributes - if not flushstreamobject then - flushstreamobject=function(data) - return pdf.obj { immediate=true,type="stream",string=data } - end - end - if not setfontattributes then - setfontattributes=function(id,data) - return pdf.setfontattributes(id,data) - end - end - function tfm.addtounicode(tfmdata) - local id=tfmdata.usedbitmap - local map={} - local char={} - for k,v in next,tfmdata.characters do - local index=v.oindex - local tounicode=v.tounicode - if index and tounicode then - map[index]=tounicode - end - end - for k,v in sortedhash(map) do - char[#char+1]=format("<%02X> <%s>",k,v) - end - char=concat(char,"\n") - local stream=format(template,id,id,#char,char) - local reference=flushstreamobject(stream,nil,true) - setfontattributes(id,format("/ToUnicode %i 0 R",reference)) - end -end -do - local everywhere={ ["*"]={ ["*"]=true } } - local noflags={ false,false,false,false } - local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local characters=data.characters - for u,c in next,characters do - local l=c.ligatures - local k=c.kerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v.char } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - end - for u,l in next,ligatures do - for k,v in next,l do - local vl=v.ligature - local dl=ligatures[vl] - if dl then - for kk,vv in next,dl do - v[kk]=vv - end - end - end - end - local features={ - gpos={}, - gsub={}, - } - local sequences={ - } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } - end - data.resources.features=features - data.resources.sequences=sequences - data.shared.resources=data.shared.resources or resources - end - registertfmenhancer("normalize features",enhance_normalize_features) - registertfmenhancer("check extra features",otfenhancers.enhance) -end -registertfmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } -} -registertfmfeature { - name="features", - description="features", - default=true, - initializers={ - base=otf.basemodeinitializer, - node=otf.nodemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- - -if not modules then modules={} end modules ['font-lua']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local report_lua=logs.reporter("fonts","lua loading") -local fonts=fonts -local readers=fonts.readers -fonts.formats.lua="lua" -local function check_lua(specification,fullname) - local fullname=resolvers.findfile(fullname) or "" - if fullname~="" then - local loader=loadfile(fullname) - loader=loader and loader() - return loader and loader(specification) - end -end -readers.check_lua=check_lua -function readers.lua(specification) - local original=specification.specification - if trace_defining then - report_lua("using lua reader for %a",original) - end - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end - end - return check_lua(specification,fullname) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def” 226b4d26ede7fa7be8e45b7f0d93e781] --- - -if not modules then modules={} end modules ['font-def']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lower,gsub=string.lower,string.gsub -local tostring,next=tostring,next -local lpegmatch=lpeg.match -local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename -local formatters=string.formatters -local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys -local allocate=utilities.storage.allocate -local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) -local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) -trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading") -local report_defining=logs.reporter("fonts","defining") -local fonts=fonts -local fontdata=fonts.hashes.identifiers -local readers=fonts.readers -local definers=fonts.definers -local specifiers=fonts.specifiers -local constructors=fonts.constructors -local fontgoodies=fonts.goodies -readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' } -local variants=allocate() -specifiers.variants=variants -definers.methods=definers.methods or {} -local internalized=allocate() -local loadedfonts=constructors.loadedfonts -local designsizes=constructors.designsizes -local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end -local function makespecification(specification,lookup,name,sub,method,detail,size) - size=size or 655360 - if not lookup or lookup=="" then - lookup=definers.defaultlookup - end - if trace_defining then - report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", - specification,lookup,name,sub,method,detail) - end - local t={ - lookup=lookup, - specification=specification, - size=size, - name=name, - sub=sub, - method=method, - detail=detail, - resolved="", - forced="", - features={}, - } - return t -end -definers.makespecification=makespecification -if context then - local splitter,splitspecifiers=nil,"" - local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs - local left=P("(") - local right=P(")") - local colon=P(":") - local space=P(" ") - local lbrace=P("{") - local rbrace=P("}") - definers.defaultlookup="file" - local prefixpattern=P(false) - local function addspecifier(symbol) - splitspecifiers=splitspecifiers..symbol - local method=S(splitspecifiers) - local lookup=C(prefixpattern)*colon - local sub=left*C(P(1-left-right-method)^1)*right - local specification=C(method)*C(P(1)^1) - local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1) - splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc(""))) - end - local function addlookup(str) - prefixpattern=prefixpattern+P(str) - end - definers.addlookup=addlookup - addlookup("file") - addlookup("name") - addlookup("spec") - local function getspecification(str) - return lpegmatch(splitter,str or "") - end - definers.getspecification=getspecification - function definers.registersplit(symbol,action,verbosename) - addspecifier(symbol) - variants[symbol]=action - if verbosename then - variants[verbosename]=action - end - end - function definers.analyze(specification,size) - local lookup,name,sub,method,detail=getspecification(specification or "") - return makespecification(specification,lookup,name,sub,method,detail,size) - end -end -definers.resolvers=definers.resolvers or {} -local resolvers=definers.resolvers -function resolvers.file(specification) - local name=resolvefile(specification.name) - local suffix=lower(suffixonly(name)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=name - specification.name=removesuffix(name) - else - specification.name=name - end -end -function resolvers.name(specification) - local resolve=fonts.names.resolve - if resolve then - local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - if instance then - specification.instance=instance - local features=specification.features - if not features then - features={} - specification.features=features - end - local normal=features.normal - if not normal then - normal={} - features.normal=normal - end - normal.instance=instance - end - local suffix=lower(suffixonly(resolved)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=resolved - specification.name=removesuffix(resolved) - else - specification.name=resolved - end - end - else - resolvers.file(specification) - end -end -function resolvers.spec(specification) - local resolvespec=fonts.names.resolvespec - if resolvespec then - local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - specification.forced=lower(suffixonly(resolved)) - specification.forcedname=resolved - specification.name=removesuffix(resolved) - end - else - resolvers.name(specification) - end -end -function definers.resolve(specification) - if not specification.resolved or specification.resolved=="" then - local r=resolvers[specification.lookup] - if r then - r(specification) - end - end - if specification.forced=="" then - specification.forced=nil - specification.forcedname=nil - end - specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) - if specification.sub and specification.sub~="" then - specification.hash=specification.sub..' @ '..specification.hash - end - return specification -end -function definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - local properties=tfmdata.properties - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=gsub(lower(extrahash),"[^a-z]","-") - properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) - end - end - end - return tfmdata -end -local function checkembedding(tfmdata) - local properties=tfmdata.properties - local embedding - if directive_embedall then - embedding="full" - elseif properties and properties.filename and constructors.dontembed[properties.filename] then - embedding="no" - else - embedding="subset" - end - if properties then - properties.embedding=embedding - else - tfmdata.properties={ embedding=embedding } - end - tfmdata.embedding=embedding -end -local function checkfeatures(tfmdata) - local resources=tfmdata.resources - local shared=tfmdata.shared - if resources and shared then - local features=resources.features - local usedfeatures=shared.features - if features and usedfeatures then - local usedlanguage=usedfeatures.language or "dflt" - local usedscript=usedfeatures.script or "dflt" - local function check(what) - if what then - local foundlanguages={} - for feature,scripts in next,what do - if usedscript=="auto" or scripts["*"] then - elseif not scripts[usedscript] then - else - for script,languages in next,scripts do - if languages["*"] then - elseif context and not languages[usedlanguage] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,usedlanguage) - end - end - end - for script,languages in next,scripts do - for language in next,languages do - foundlanguages[language]=true - end - end - end - if false then - foundlanguages["*"]=nil - foundlanguages=sortedkeys(foundlanguages) - for feature,scripts in sortedhash(what) do - for script,languages in next,scripts do - if not languages["*"] then - for i=1,#foundlanguages do - local language=foundlanguages[i] - if context and not languages[language] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,language) - end - end - end - end - end - end - end - end - check(features.gsub) - check(features.gpos) - end - end -end -function definers.loadfont(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=loadedfonts[hash] - if not tfmdata then - local forced=specification.forced or "" - if forced~="" then - local reader=readers[lower(forced)] - tfmdata=reader and reader(specification) - if not tfmdata then - report_defining("forced type %a of %a not found",forced,specification.name) - end - else - local sequence=readers.sequence - for s=1,#sequence do - local reader=sequence[s] - if readers[reader] then - if trace_defining then - report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) - end - tfmdata=readers[reader](specification) - if tfmdata then - break - else - specification.filename=nil - end - end - end - end - if tfmdata then - tfmdata=definers.applypostprocessors(tfmdata) - checkembedding(tfmdata) - loadedfonts[hash]=tfmdata - designsizes[specification.hash]=tfmdata.parameters.designsize - checkfeatures(tfmdata) - end - end - if not tfmdata then - report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) - end - return tfmdata -end -function constructors.readanddefine(name,size) - local specification=definers.analyze(name,size) - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) - end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local id=definers.registered(hash) - if not id then - local tfmdata=definers.loadfont(specification) - if tfmdata then - tfmdata.properties.hash=hash - id=font.define(tfmdata) - definers.register(tfmdata,id) - else - id=0 - end - end - return fontdata[id],id -end -function definers.registered(hash) - local id=internalized[hash] - return id,id and fontdata[id] -end -function definers.register(tfmdata,id) - if tfmdata and id then - local hash=tfmdata.properties.hash - if not hash then - report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") - elseif not internalized[hash] then - internalized[hash]=id - if trace_defining then - report_defining("registering font, id %s, hash %a",id,hash) - end - fontdata[id]=tfmdata - end - end -end -function definers.read(specification,size,id) - statistics.starttiming(fonts) - if type(specification)=="string" then - specification=definers.analyze(specification,size) - end - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) - end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=definers.registered(hash) - if tfmdata then - if trace_defining then - report_defining("already hashed: %s",hash) - end - else - tfmdata=definers.loadfont(specification) - if tfmdata then - tfmdata.original=specification.specification - if trace_defining then - report_defining("loaded and hashed: %s",hash) - end - tfmdata.properties.hash=hash - if id then - definers.register(tfmdata,id) - end - else - if trace_defining then - report_defining("not loaded and hashed: %s",hash) - end - end - end - if not tfmdata then - report_defining("unknown font %a, loading aborted",specification.name) - elseif trace_defining and type(tfmdata)=="table" then - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", - properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, - properties.encodingname,properties.fullname,basename(properties.filename)) - end - statistics.stoptiming(fonts) - return tfmdata -end -function font.getfont(id) - return fontdata[id] -end -if not context then - callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp” c4a8c14513597ce3579d3ad4c580fe51] --- - -if not modules then modules={} end modules ['font-shp']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local tonumber,next=tonumber,next -local concat=table.concat -local formatters=string.formatters -local otf=fonts.handlers.otf -local afm=fonts.handlers.afm -local pfb=fonts.handlers.pfb -local hashes=fonts.hashes -local identifiers=hashes.identifiers -local version=0.009 -local shapescache=containers.define("fonts","shapes",version,true) -local streamscache=containers.define("fonts","streams",version,true) -local compact_streams=false -directives.register("fonts.streams.compact",function(v) compact_streams=v end) -local function packoutlines(data,makesequence) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - packoutlines(subfonts[i],makesequence) - end - return - end - local common=data.segments - if common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - if makesequence then - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - local sequence={} - local nofsequence=0 - for i=1,#segments do - local segment=segments[i] - local nofsegment=#segment - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[nofsegment] - for i=1,nofsegment-1 do - nofsequence=nofsequence+1 - sequence[nofsequence]=segment[i] - end - end - glyph.sequence=sequence - glyph.segments=nil - end - end - end - else - local hash={} - local common={} - local reverse={} - local last=0 - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local h=concat(segments[i]," ") - hash[h]=(hash[h] or 0)+1 - end - end - end - end - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local segment=segments[i] - local h=concat(segment," ") - if hash[h]>1 then - local idx=reverse[h] - if not idx then - last=last+1 - reverse[h]=last - common[last]=segment - idx=last - end - segments[i]=idx - end - end - end - end - end - if last>0 then - data.segments=common - end - end -end -local function unpackoutlines(data) - local subfonts=data.subfonts - if subfonts then - for i=1,#subfonts do - unpackoutlines(subfonts[i]) - end - return - end - local common=data.segments - if not common then - return - end - local glyphs=data.glyphs - if not glyphs then - return - end - for index=0,#glyphs do - local glyph=glyphs[index] - if glyph then - local segments=glyph.segments - if segments then - for i=1,#segments do - local c=common[segments[i]] - if c then - segments[i]=c - end - end - end - end - end - data.segments=nil -end -local readers=otf.readers -local cleanname=otf.readers.helpers.cleanname -local function makehash(filename,sub,instance) - local name=cleanname(file.basename(filename)) - if instance then - return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance)) - else - return formatters["%s-%s"] (name,sub or 0) - end -end -local function loadoutlines(cache,filename,sub,instance) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=file.suffix(filename) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=otf.readers.loadshapes(filename,sub,instance) - if data then - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - packoutlines(data) - containers.write(cache,hash,data) - data=containers.read(cache,hash) - end - end - unpackoutlines(data) - elseif size>0 and (kind=="pfb") then - local hash=containers.cleanname(base) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=afm.readers.loadshapes(filename) - if data then - data.size=size - data.format="type1" - data.time=time - packoutlines(data) - containers.write(cache,hash,data) - data=containers.read(cache,hash) - end - end - unpackoutlines(data) - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - units=1000, - glyphs={} - } - end - return data -end -local function cachethem(cache,hash,data) - containers.write(cache,hash,data,compact_streams) - return containers.read(cache,hash) -end -local function loadstreams(cache,filename,sub,instance) - local base=file.basename(filename) - local name=file.removesuffix(base) - local kind=file.suffix(filename) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - local sub=tonumber(sub) - if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - data=otf.readers.loadshapes(filename,sub,instance,true) - if data then - local glyphs=data.glyphs - local streams={} - if glyphs then - for i=0,#glyphs do - local glyph=glyphs[i] - if glyph then - streams[i]=glyph.stream or "" - else - streams[i]="" - end - end - end - data.streams=streams - data.glyphs=nil - data.size=size - data.format=data.format or (kind=="otf" and "opentype") or "truetype" - data.time=time - data=cachethem(cache,hash,data) - end - end - elseif size>0 and (kind=="pfb") then - local hash=makehash(filename,sub,instance) - data=containers.read(cache,hash) - if not data or data.time~=time or data.size~=size then - local names,encoding,streams,metadata=pfb.loadvector(filename,false,true) - if streams then - local fontbbox=metadata.fontbbox or { 0,0,0,0 } - for i=0,#streams do - streams[i]=streams[i].stream or "\14" - end - data={ - filename=filename, - size=size, - time=time, - format="type1", - streams=streams, - fontheader={ - fontversion=metadata.version, - units=1000, - xmin=fontbbox[1], - ymin=fontbbox[2], - xmax=fontbbox[3], - ymax=fontbbox[4], - }, - horizontalheader={ - ascender=0, - descender=0, - }, - maximumprofile={ - nofglyphs=#streams+1, - }, - names={ - copyright=metadata.copyright, - family=metadata.familyname, - fullname=metadata.fullname, - fontname=metadata.fontname, - subfamily=metadata.subfamilyname, - trademark=metadata.trademark, - notice=metadata.notice, - version=metadata.version, - }, - cffinfo={ - familyname=metadata.familyname, - fullname=metadata.fullname, - italicangle=metadata.italicangle, - monospaced=metadata.isfixedpitch and true or false, - underlineposition=metadata.underlineposition, - underlinethickness=metadata.underlinethickness, - weight=metadata.weight, - }, - } - data=cachethem(cache,hash,data) - end - end - else - data={ - filename=filename, - size=0, - time=time, - format="unknown", - streams={} - } - end - return data -end -local loadedshapes={} -local loadedstreams={} -local function loadoutlinedata(fontdata,streams) - local properties=fontdata.properties - local filename=properties.filename - local subindex=fontdata.subindex - local instance=properties.instance - local hash=makehash(filename,subindex,instance) - local loaded=loadedshapes[hash] - if not loaded then - loaded=loadoutlines(shapescache,filename,subindex,instance) - loadedshapes[hash]=loaded - end - return loaded -end -hashes.shapes=table.setmetatableindex(function(t,k) - local f=identifiers[k] - if f then - return loadoutlinedata(f) - end -end) -local function getstreamhash(fontid) - local fontdata=identifiers[fontid] - if fontdata then - local properties=fontdata.properties - return makehash(properties.filename,properties.subfont,properties.instance) - end -end -local function loadstreamdata(fontdata) - local properties=fontdata.properties - local shared=fontdata.shared - local rawdata=shared and shared.rawdata - local metadata=rawdata and rawdata.metadata - local filename=properties.filename - local subindex=metadata and metadata.subfontindex - local instance=properties.instance - local hash=makehash(filename,subindex,instance) - local loaded=loadedstreams[hash] - if not loaded then - loaded=loadstreams(streamscache,filename,subindex,instance) - loadedstreams[hash]=loaded - end - return loaded -end -hashes.streams=table.setmetatableindex(function(t,k) - local f=identifiers[k] - if f then - return loadstreamdata(f) - end -end) -otf.loadoutlinedata=loadoutlinedata -otf.loadstreamdata=loadstreamdata -otf.loadshapes=loadshapes -otf.getstreamhash=getstreamhash -local streams=fonts.hashes.streams -callback.register("glyph_stream_provider",function(id,index,mode) - if id>0 then - local streams=streams[id].streams - if streams then - return streams[index] or "" - end - end - return "" -end) - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- - -if not modules then modules={} end modules ['luatex-fonts-def']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local fonts=fonts -fonts.constructors.namemode="specification" -function fonts.definers.getspecification(str) - return "",str,"",":",str -end -local list={} -local function issome () list.lookup='name' end -local function isfile () list.lookup='file' end -local function isname () list.lookup='name' end -local function thename(s) list.name=s end -local function issub (v) list.sub=v end -local function iscrap (s) list.crap=string.lower(s) end -local function iskey (k,v) list[k]=v end -local function istrue (s) list[s]=true end -local function isfalse(s) list[s]=false end -local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs -local spaces=P(" ")^0 -local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0) -local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces -local filename_1=P("file:")/isfile*(namespec/thename) -local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]") -local fontname_1=P("name:")/isname*(namespec/thename) -local fontname_2=P(true)/issome*(namespec/thename) -local sometext=R("az","AZ","09")^1 -local somekey=R("az","AZ","09")^1 -local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1 -local truevalue=P("+")*spaces*(sometext/istrue) -local falsevalue=P("-")*spaces*(sometext/isfalse) -local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey -local somevalue=sometext/istrue -local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")") -local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces -local options=P(":")*spaces*(P(";")^0*option)^0 -local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0 -function fonts.definers.analyze(str,size) - local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) - list={} - lpeg.match(pattern,str) - list.crap=nil - if list.name then - specification.name=list.name - list.name=nil - end - if list.lookup then - specification.lookup=list.lookup - list.lookup=nil - end - if list.sub then - specification.sub=list.sub - list.sub=nil - end - specification.features.normal=fonts.handlers.otf.features.normalize(list) - list=nil - return specification -end -function fonts.definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=string.gsub(lower(extrahash),"[^a-z]","-") - tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) - end - end - end - return tfmdata -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- - -if not modules then modules={} end modules ['luatex-fonts-ext']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local byte=string.byte -local fonts=fonts -local handlers=fonts.handlers -local otf=handlers.otf -local afm=handlers.afm -local registerotffeature=otf.features.register -local registerafmfeature=afm.features.register -function fonts.loggers.onetimemessage() end -fonts.protrusions=fonts.protrusions or {} -fonts.protrusions.setups=fonts.protrusions.setups or {} -local setups=fonts.protrusions.setups -setups['default']={ - factor=1, - left=1, - right=1, - [0x002C]={ 0,1 }, - [0x002E]={ 0,1 }, - [0x003A]={ 0,1 }, - [0x003B]={ 0,1 }, - [0x002D]={ 0,1 }, - [0x2013]={ 0,0.50 }, - [0x2014]={ 0,0.33 }, - [0x3001]={ 0,1 }, - [0x3002]={ 0,1 }, - [0x060C]={ 0,1 }, - [0x061B]={ 0,1 }, - [0x06D4]={ 0,1 }, -} -local function initializeprotrusion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 - local emwidth=tfmdata.parameters.quad - tfmdata.parameters.protrusion={ - auto=true, - } - for i,chr in next,tfmdata.characters do - local v,pl,pr=setup[i],nil,nil - if v then - pl,pr=v[1],v[2] - end - if pl and pl~=0 then chr.left_protruding=left*pl*factor end - if pr and pr~=0 then chr.right_protruding=right*pr*factor end - end - end - end -end -local specification={ - name="protrusion", - description="shift characters into the left and or right margin", - initializers={ - base=initializeprotrusion, - node=initializeprotrusion, - } -} -registerotffeature(specification) -registerafmfeature(specification) -fonts.expansions=fonts.expansions or {} -fonts.expansions.setups=fonts.expansions.setups or {} -local setups=fonts.expansions.setups -setups['default']={ - stretch=2, - shrink=2, - step=.5, - factor=1, - [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, - [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, - [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, - [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, - [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, - [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, - [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, - [byte('w')]=0.7,[byte('z')]=0.7, - [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, -} -local function initializeexpansion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor=setup.factor or 1 - tfmdata.parameters.expansion={ - stretch=10*(setup.stretch or 0), - shrink=10*(setup.shrink or 0), - step=10*(setup.step or 0), - auto=true, - } - for i,chr in next,tfmdata.characters do - local v=setup[i] - if v and v~=0 then - chr.expansion_factor=v*factor - else - chr.expansion_factor=factor - end - end - end - end -end -local specification={ - name="expansion", - description="apply hz optimization", - initializers={ - base=initializeexpansion, - node=initializeexpansion, - } -} -registerotffeature(specification) -registerafmfeature(specification) -if not otf.features.normalize then - otf.features.normalize=function(t) - if t.rand then - t.rand="random" - end - return t - end -end -function fonts.helpers.nametoslot(name) - local t=type(name) - if t=="string" then - local tfmdata=fonts.hashes.identifiers[currentfont()] - local shared=tfmdata and tfmdata.shared - local fntdata=shared and shared.rawdata - return fntdata and fntdata.resources.unicodes[name] - elseif t=="number" then - return n - end -end -fonts.encodings=fonts.encodings or {} -local reencodings={} -fonts.encodings.reencodings=reencodings -local function specialreencode(tfmdata,value) - local encoding=value and reencodings[value] - if encoding then - local temp={} - local char=tfmdata.characters - for k,v in next,encoding do - temp[k]=char[v] - end - for k,v in next,temp do - char[k]=temp[k] - end - return string.format("reencoded:%s",value) - end -end -local function initialize(tfmdata,value) - tfmdata.postprocessors=tfmdata.postprocessors or {} - table.insert(tfmdata.postprocessors, - function(tfmdata) - return specialreencode(tfmdata,value) - end - ) -end -registerotffeature { - name="reencode", - description="reencode characters", - manipulators={ - base=initialize, - node=initialize, - } -} -local function initialize(tfmdata,key,value) - if value then - tfmdata.mathparameters=nil - end -end -registerotffeature { - name="ignoremathconstants", - description="ignore math constants table", - initializers={ - base=initialize, - node=initialize, - } -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- - -if not modules then modules={} end modules ['font-imp-tex']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next=next -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local addotffeature=otf.addfeature -local specification={ - type="ligature", - order={ "tlig" }, - prepend=true, - data={ - [0x2013]={ 0x002D,0x002D }, - [0x2014]={ 0x002D,0x002D,0x002D }, - }, -} -addotffeature("tlig",specification) -registerotffeature { - name="tlig", - description="tex ligatures", -} -local specification={ - type="substitution", - order={ "trep" }, - prepend=true, - data={ - [0x0027]=0x2019, - }, -} -addotffeature("trep",specification) -registerotffeature { - name="trep", - description="tex replacements", -} -local anum_arabic={ - [0x0030]=0x0660, - [0x0031]=0x0661, - [0x0032]=0x0662, - [0x0033]=0x0663, - [0x0034]=0x0664, - [0x0035]=0x0665, - [0x0036]=0x0666, - [0x0037]=0x0667, - [0x0038]=0x0668, - [0x0039]=0x0669, -} -local anum_persian={ - [0x0030]=0x06F0, - [0x0031]=0x06F1, - [0x0032]=0x06F2, - [0x0033]=0x06F3, - [0x0034]=0x06F4, - [0x0035]=0x06F5, - [0x0036]=0x06F6, - [0x0037]=0x06F7, - [0x0038]=0x06F8, - [0x0039]=0x06F9, -} -local function valid(data) - local features=data.resources.features - if features then - for k,v in next,features do - for k,v in next,v do - if v.arab then - return true - end - end - end - end -end -local specification={ - { - type="substitution", - features={ arab={ urd=true,dflt=true } }, - order={ "anum" }, - data=anum_arabic, - valid=valid, - }, - { - type="substitution", - features={ arab={ urd=true } }, - order={ "anum" }, - data=anum_persian, - valid=valid, - }, -} -addotffeature("anum",specification) -registerotffeature { - name="anum", - description="arabic digits", -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- - -if not modules then modules={} end modules ['font-imp-ligatures']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local lpegmatch=lpeg.match -local utfsplit=utf.split -local settings_to_array=utilities.parsers.settings_to_array -local fonts=fonts -local otf=fonts.handlers.otf -local registerotffeature=otf.features.register -local addotffeature=otf.addfeature -local lookups={} -local protect={} -local revert={} -local zwjchar=0x200C -local zwj={ zwjchar } -addotffeature { - name="blockligatures", - type="chainsubstitution", - nocheck=true, - prepend=true, - future=true, - lookups={ - { - type="multiple", - data=lookups, - }, - }, - data={ - rules=protect, - } -} -addotffeature { - name="blockligatures", - type="chainsubstitution", - nocheck=true, - append=true, - overload=false, - lookups={ - { - type="ligature", - data=lookups, - }, - }, - data={ - rules=revert, - } -} -registerotffeature { - name='blockligatures', - description='block certain ligatures', -} -local splitter=lpeg.splitat(":") -local function blockligatures(str) - local t=settings_to_array(str) - for i=1,#t do - local ti=t[i] - local before,current,after=lpegmatch(splitter,ti) - if current and after then - if before then - before=utfsplit(before) - for i=1,#before do - before[i]={ before[i] } - end - end - if current then - current=utfsplit(current) - end - if after then - after=utfsplit(after) - for i=1,#after do - after[i]={ after[i] } - end - end - else - before=nil - current=utfsplit(ti) - after=nil - end - if #current>1 then - local one=current[1] - local two=current[2] - lookups[one]={ one,zwjchar } - local one={ one } - local two={ two } - local new=#protect+1 - protect[new]={ - before=before, - current={ one,two }, - after=after, - lookups={ 1 }, - } - revert[new]={ - current={ one,zwj }, - after={ two }, - lookups={ 1 }, - } - end - end -end -otf.helpers.blockligatures=blockligatures -if context then - interfaces.implement { - name="blockligatures", - arguments="string", - actions=blockligatures, - } -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics” 058fb834c11c6ac30c280b29e496966e] --- - -if not modules then modules={} end modules ['font-imp-italics']={ - version=1.001, - comment="companion to font-ini.mkiv and hand-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next=next -local fonts=fonts -local handlers=fonts.handlers -local registerotffeature=handlers.otf.features.register -local registerafmfeature=handlers.afm.features.register -local function initialize(tfmdata,key,value) - for unicode,character in next,tfmdata.characters do - local olditalic=character.italic - if olditalic and olditalic~=0 then - character.width=character.width+olditalic - character.italic=0 - end - end -end -local specification={ - name="italicwidths", - description="add italic to width", - manipulators={ - base=initialize, - node=initialize, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initialize(tfmdata,value) - if value then - local parameters=tfmdata.parameters - local italicangle=parameters.italicangle - if italicangle and italicangle~=0 then - local properties=tfmdata.properties - local factor=tonumber(value) or 1 - properties.hasitalics=true - properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 - end - end -end -local specification={ - name="itlc", - description="italic correction", - initializers={ - base=initialize, - node=initialize, - } -} -registerotffeature(specification) -registerafmfeature(specification) -if context then - local function initialize(tfmdata,value) - tfmdata.properties.textitalics=toboolean(value) - end - local specification={ - name="textitalics", - description="use alternative text italic correction", - initializers={ - base=initialize, - node=initialize, - } - } - registerotffeature(specification) - registerafmfeature(specification) - local letter=characters.is_letter - local always=true - local function collapseitalics(tfmdata,key,value) - local threshold=value==true and 100 or tonumber(value) - if threshold and threshold>0 then - if threshold>100 then - threshold=100 - end - for unicode,data in next,tfmdata.characters do - if always or letter[unicode] or letter[data.unicode] then - local italic=data.italic - if italic and italic~=0 then - local width=data.width - if width and width~=0 then - local delta=threshold*italic/100 - data.width=width+delta - data.italic=italic-delta - end - end - end - end - end - end - local dimensions_specification={ - name="collapseitalics", - description="collapse italics", - manipulators={ - base=collapseitalics, - node=collapseitalics, - } - } - registerotffeature(dimensions_specification) - registerafmfeature(dimensions_specification) -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects” 582f9dd5031e9d67fff389efd16a874f] --- - -if not modules then modules={} end modules ['font-imp-effects']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type,tonumber=next,type,tonumber -local is_boolean=string.is_boolean -local fonts=fonts -local handlers=fonts.handlers -local registerotffeature=handlers.otf.features.register -local registerafmfeature=handlers.afm.features.register -local settings_to_hash=utilities.parsers.settings_to_hash_colon_too -local helpers=fonts.helpers -local prependcommands=helpers.prependcommands -local charcommand=helpers.commands.char -local leftcommand=helpers.commands.left -local rightcommand=helpers.commands.right -local upcommand=helpers.commands.up -local downcommand=helpers.commands.down -local dummycommand=helpers.commands.dummy -local report_effect=logs.reporter("fonts","effect") -local report_slant=logs.reporter("fonts","slant") -local report_extend=logs.reporter("fonts","extend") -local report_squeeze=logs.reporter("fonts","squeeze") -local trace=false -trackers.register("fonts.effect",function(v) trace=v end) -trackers.register("fonts.slant",function(v) trace=v end) -trackers.register("fonts.extend",function(v) trace=v end) -trackers.register("fonts.squeeze",function(v) trace=v end) -local function initializeslant(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>1 then - value=1 - elseif value<-1 then - value=-1 - end - if trace then - report_slant("applying %0.3f",value) - end - tfmdata.parameters.slantfactor=value -end -local specification={ - name="slant", - description="slant glyphs", - initializers={ - base=initializeslant, - node=initializeslant, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializeextend(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>10 then - value=10 - elseif value<-10 then - value=-10 - end - if trace then - report_extend("applying %0.3f",value) - end - tfmdata.parameters.extendfactor=value -end -local specification={ - name="extend", - description="scale glyphs horizontally", - initializers={ - base=initializeextend, - node=initializeextend, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializesqueeze(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>10 then - value=10 - elseif value<-10 then - value=-10 - end - if trace then - report_squeeze("applying %0.3f",value) - end - tfmdata.parameters.squeezefactor=value -end -local specification={ - name="squeeze", - description="scale glyphs vertically", - initializers={ - base=initializesqueeze, - node=initializesqueeze, - } -} -registerotffeature(specification) -registerafmfeature(specification) -local effects={ - inner=0, - normal=0, - outer=1, - outline=1, - both=2, - hidden=3, -} -local function initializeeffect(tfmdata,value) - local spec - if type(value)=="number" then - spec={ width=value } - else - spec=settings_to_hash(value) - end - local effect=spec.effect or "both" - local width=tonumber(spec.width) or 0 - local mode=effects[effect] - if not mode then - report_effect("invalid effect %a",effect) - elseif width==0 and mode==0 then - report_effect("invalid width %a for effect %a",width,effect) - else - local parameters=tfmdata.parameters - local properties=tfmdata.properties - parameters.mode=mode - parameters.width=width*1000 - if is_boolean(spec.auto)==true then - local squeeze=1-width/20 - local average=(1-squeeze)*width*100 - spec.squeeze=squeeze - spec.extend=1+width/2 - spec.wdelta=average - spec.hdelta=average/2 - spec.ddelta=average/2 - spec.vshift=average/2 - end - local factor=tonumber(spec.factor) or 0 - local hfactor=tonumber(spec.hfactor) or factor - local vfactor=tonumber(spec.vfactor) or factor - local delta=tonumber(spec.delta) or 1 - local wdelta=tonumber(spec.wdelta) or delta - local hdelta=tonumber(spec.hdelta) or delta - local ddelta=tonumber(spec.ddelta) or hdelta - local vshift=tonumber(spec.vshift) or 0 - local slant=spec.slant - local extend=spec.extend - local squeeze=spec.squeeze - if slant then - initializeslant(tfmdata,slant) - end - if extend then - initializeextend(tfmdata,extend) - end - if squeeze then - initializesqueeze(tfmdata,squeeze) - end - properties.effect={ - effect=effect, - width=width, - factor=factor, - hfactor=hfactor, - vfactor=vfactor, - wdelta=wdelta, - hdelta=hdelta, - ddelta=ddelta, - vshift=vshift, - slant=tfmdata.parameters.slantfactor, - extend=tfmdata.parameters.extendfactor, - squeeze=tfmdata.parameters.squeezefactor, - } - end -end -local rules={ - "RadicalRuleThickness", - "OverbarRuleThickness", - "FractionRuleThickness", - "UnderbarRuleThickness", -} -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dx) - end - end - end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - local function wdpatch(char) - if wsnap~=0 then - char.width=char.width+wdelta/2 - end - end - local function htpatch(char) - if hsnap~=0 then - local height=char.height - if height then - char.height=char.height+2*dy - end - end - end - local character=characters[0x221A] - if character and character.next then - local char=character - local next=character.next - wdpatch(char) - htpatch(char) - while next do - char=characters[next] - wdpatch(char) - htpatch(char) - next=char.next - end - if char then - local v=char.vert_variants - if v then - local top=v[#v] - if top then - local char=characters[top.glyph] - htpatch(char) - end - end - end - end -end -local shiftmode=CONTEXTLMTXMODE>0 -local function manipulateeffect(tfmdata) - local effect=tfmdata.properties.effect - if effect then - local characters=tfmdata.characters - local parameters=tfmdata.parameters - local mathparameters=tfmdata.mathparameters - local multiplier=effect.width*100 - local factor=parameters.factor - local hfactor=parameters.hfactor - local vfactor=parameters.vfactor - local wdelta=effect.wdelta*hfactor*multiplier - local hdelta=effect.hdelta*vfactor*multiplier - local ddelta=effect.ddelta*vfactor*multiplier - local vshift=effect.vshift*vfactor*multiplier - local squeeze=effect.squeeze - local hshift=wdelta/2 - local dx=multiplier*vfactor - local dy=vshift - local factor=(1+effect.factor)*factor - local hfactor=(1+effect.hfactor)*hfactor - local vfactor=(1+effect.vfactor)*vfactor - if shiftmode then - parameters.hshift=hshift - parameters.vshift=vshift - else - vshift=vshift~=0 and upcommand[vshift] or false - hshift=rightcommand[hshift] - end - for unicode,character in next,characters do - local oldwidth=character.width - local oldheight=character.height - local olddepth=character.depth - if oldwidth and oldwidth>0 then - character.width=oldwidth+wdelta - if not shiftmode then - local commands=character.commands - if vshift then - if commands then - prependcommands (commands, - hshift, - vshift - ) - else - character.commands={ - hshift, - vshift, - charcommand[unicode] - } - end - else - if commands then - prependcommands (commands, - hshift - ) - else - character.commands={ - hshift, - charcommand[unicode] - } - end - end - end - end - if oldheight and oldheight>0 then - character.height=oldheight+hdelta - end - if olddepth and olddepth>0 then - character.depth=olddepth+ddelta - end - end - if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - end - parameters.factor=factor - parameters.hfactor=hfactor - parameters.vfactor=vfactor - if trace then - report_effect("applying") - report_effect(" effect : %s",effect.effect) - report_effect(" width : %s => %s",effect.width,multiplier) - report_effect(" factor : %s => %s",effect.factor,factor ) - report_effect(" hfactor : %s => %s",effect.hfactor,hfactor) - report_effect(" vfactor : %s => %s",effect.vfactor,vfactor) - report_effect(" wdelta : %s => %s",effect.wdelta,wdelta) - report_effect(" hdelta : %s => %s",effect.hdelta,hdelta) - report_effect(" ddelta : %s => %s",effect.ddelta,ddelta) - end - end -end -local specification={ - name="effect", - description="apply effects to glyphs", - initializers={ - base=initializeeffect, - node=initializeeffect, - }, - manipulators={ - base=manipulateeffect, - node=manipulateeffect, - }, -} -registerotffeature(specification) -registerafmfeature(specification) -local function initializeoutline(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - else - value=tonumber(value) or 0 - end - local parameters=tfmdata.parameters - local properties=tfmdata.properties - parameters.mode=effects.outline - parameters.width=value*1000 - properties.effect={ - effect=effect, - width=width, - } -end -local specification={ - name="outline", - description="outline glyphs", - initializers={ - base=initializeoutline, - node=initializeoutline, - } -} -registerotffeature(specification) -registerafmfeature(specification) - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- - - -fonts.handlers.otf.addfeature { - ["dataset"]={ - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, - }, - }, - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, - }, - }, - }, - ["name"]="collapse", - ["prepend"]=true, - ["type"]="ligature", -} - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig”] --- - - -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- - -if not modules then modules={} end modules ['luatex-fonts-gbn']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -if context then - os.exit() -end -local next=next -local fonts=fonts -local nodes=nodes -local nuts=nodes.nuts -local traverse_id=nuts.traverse_id -local flush_node=nuts.flush_node -local glyph_code=nodes.nodecodes.glyph -local disc_code=nodes.nodecodes.disc -local tonode=nuts.tonode -local tonut=nuts.tonut -local getfont=nuts.getfont -local getchar=nuts.getchar -local getid=nuts.getid -local getboth=nuts.getboth -local getprev=nuts.getprev -local getnext=nuts.getnext -local getdisc=nuts.getdisc -local setchar=nuts.setchar -local setlink=nuts.setlink -local setprev=nuts.setprev -local n_ligaturing=node.ligaturing -local n_kerning=node.kerning -local d_ligaturing=nuts.ligaturing -local d_kerning=nuts.kerning -local basemodepass=true -local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end -local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end -function node.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return n_ligaturing(...) -end -function node.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return n_kerning(...) -end -function nuts.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return d_ligaturing(...) -end -function nuts.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return d_kerning(...) -end -function nodes.handlers.setbasemodepass(v) - basemodepass=v -end -local function nodepass(head,groupcode,size,packtype,direction) - local fontdata=fonts.hashes.identifiers - if fontdata then - local usedfonts={} - local basefonts={} - local prevfont=nil - local basefont=nil - local variants=nil - local redundant=nil - local nofused=0 - for n in traverse_id(glyph_code,head) do - local font=getfont(n) - if font~=prevfont then - if basefont then - basefont[2]=getprev(n) - end - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - elseif basemodepass then - basefont={ n,nil } - basefonts[#basefonts+1]=basefont - end - end - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - else - local tfmdata=fontdata[prevfont] - if tfmdata then - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - end - end - if variants then - local char=getchar(n) - if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then - local hash=variants[char] - if hash then - local p=getprev(n) - if p and getid(p)==glyph_code then - local variant=hash[getchar(p)] - if variant then - setchar(p,variant) - end - end - end - if not redundant then - redundant={ n } - else - redundant[#redundant+1]=n - end - end - end - end - local nofbasefonts=#basefonts - if redundant then - for i=1,#redundant do - local r=redundant[i] - local p,n=getboth(r) - if r==head then - head=n - setprev(n) - else - setlink(p,n) - end - if nofbasefonts>0 then - for i=1,nofbasefonts do - local bi=basefonts[i] - if r==bi[1] then - bi[1]=n - end - if r==bi[2] then - bi[2]=n - end - end - end - flush_node(r) - end - end - for d in traverse_id(disc_code,head) do - local _,_,r=getdisc(d) - if r then - for n in traverse_id(glyph_code,r) do - local font=getfont(n) - if font~=prevfont then - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - end - end - end - end - end - end - end - end - if next(usedfonts) then - for font,processors in next,usedfonts do - for i=1,#processors do - head=processors[i](head,font,0,direction,nofused) or head - end - end - end - if basemodepass and nofbasefonts>0 then - for i=1,nofbasefonts do - local range=basefonts[i] - local start=range[1] - local stop=range[2] - if start then - local front=head==start - local prev,next - if stop then - next=getnext(stop) - start,stop=d_ligaturing(start,stop) - start,stop=d_kerning(start,stop) - else - prev=getprev(start) - start=d_ligaturing(start) - start=d_kerning(start) - end - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - if front and head~=start then - head=start - end - end - end - end - end - return head -end -local function basepass(head) - if basemodepass then - head=d_ligaturing(head) - head=d_kerning(head) - end - return head -end -local protectpass=node.direct.protect_glyphs -local injectpass=nodes.injections.handler -function nodes.handlers.nodepass(head,...) - if head then - return tonode(nodepass(tonut(head),...)) - end -end -function nodes.handlers.basepass(head) - if head then - return tonode(basepass(tonut(head))) - end -end -function nodes.handlers.injectpass(head) - if head then - return tonode(injectpass(tonut(head))) - end -end -function nodes.handlers.protectpass(head) - if head then - protectpass(tonut(head)) - return head - end -end -function nodes.simple_font_handler(head,groupcode,size,packtype,direction) - if head then - head=tonut(head) - head=nodepass(head,groupcode,size,packtype,direction) - head=injectpass(head) - if not basemodepass then - head=basepass(head) - end - protectpass(head) - head=tonode(head) - end - return head -end - -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn”] --- - - ---- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua b/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua new file mode 100644 index 0000000000..835eca6695 --- /dev/null +++ b/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua @@ -0,0 +1,35110 @@ +--[[info----------------------------------------------------------------------- + Luaotfload fontloader package + build 2020-12-30 17:29:34 +------------------------------------------------------------------------------- + + © 2020 PRAGMA ADE / ConTeXt Development Team + + The code in this file is provided under the GPL v2.0 license. See the + file COPYING in the Luaotfload repository for details. + + Report bugs to https://github.com/latex3/luaotfload + + This file has been assembled from components taken from Context. See + the Luaotfload documentation for details: + + $ texdoc luaotfload + $ man 1 luaotfload-tool + $ man 5 luaotfload.conf + + Included files: + + · fontloader-data-con.lua + · fontloader-basics-nod.lua + · fontloader-basics-chr.lua + · fontloader-font-ini.lua + · fontloader-fonts-mis.lua + · fontloader-font-con.lua + · fontloader-fonts-enc.lua + · fontloader-font-cid.lua + · fontloader-font-map.lua + · fontloader-font-vfc.lua + · fontloader-font-otr.lua + · fontloader-font-oti.lua + · fontloader-font-ott.lua + · fontloader-font-cff.lua + · fontloader-font-ttf.lua + · fontloader-font-dsp.lua + · fontloader-font-oup.lua + · fontloader-font-otl.lua + · fontloader-font-oto.lua + · fontloader-font-otj.lua + · fontloader-font-ota.lua + · fontloader-font-ots.lua + · fontloader-font-osd.lua + · fontloader-font-ocl.lua + · fontloader-font-otc.lua + · fontloader-font-onr.lua + · fontloader-font-one.lua + · fontloader-font-afk.lua + · fontloader-fonts-tfm.lua + · fontloader-font-lua.lua + · fontloader-font-def.lua + · fontloader-font-shp.lua + · fontloader-fonts-def.lua + · fontloader-fonts-ext.lua + · fontloader-font-imp-tex.lua + · fontloader-font-imp-ligatures.lua + · fontloader-font-imp-italics.lua + · fontloader-font-imp-effects.lua + · fontloader-fonts-lig.lua + · fontloader-fonts-gbn.lua + +--info]]----------------------------------------------------------------------- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] --- + +if not modules then modules={} end modules ['data-con']={ + version=1.100, + comment="companion to luat-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local setmetatable=setmetatable +local format,lower,gsub=string.format,string.lower,string.gsub +local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) +local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) +local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end) +containers=containers or {} +local containers=containers +containers.usecache=true +local getwritablepath=caches.getwritablepath +local getreadablepaths=caches.getreadablepaths +local cacheiswritable=caches.is_writable +local loaddatafromcache=caches.loaddata +local savedataincache=caches.savedata +local report_containers=logs.reporter("resolvers","containers") +local allocated={} +local mt={ + __index=function(t,k) + if k=="writable" then + local writable=getwritablepath(t.category,t.subcategory) or { "." } + t.writable=writable + return writable + elseif k=="readables" then + local readables=getreadablepaths(t.category,t.subcategory) or { "." } + t.readables=readables + return readables + end + end, + __storage__=true +} +function containers.define(category,subcategory,version,enabled) + if category and subcategory then + local c=allocated[category] + if not c then + c={} + allocated[category]=c + end + local s=c[subcategory] + if not s then + s={ + category=category, + subcategory=subcategory, + storage={}, + enabled=enabled, + version=version or math.pi, + trace=false, + } + setmetatable(s,mt) + c[subcategory]=s + end + return s + end +end +function containers.is_usable(container,name) + return container.enabled and caches and cacheiswritable(container.writable,name) +end +function containers.is_valid(container,name) + if name and name~="" then + local storage=container.storage[name] + return storage and storage.cache_version==container.version + else + return false + end +end +function containers.read(container,name) + local storage=container.storage + local stored=storage[name] + if not stored and container.enabled and caches and containers.usecache then + stored=loaddatafromcache(container.readables,name,container.writable) + if stored and stored.cache_version==container.version then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","load",container.subcategory,name) + end + else + stored=nil + end + storage[name]=stored + elseif stored then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) + end + end + return stored +end +function containers.write(container,name,data,fast) + if data then + data.cache_version=container.version + if container.enabled and caches then + local unique=data.unique + local shared=data.shared + data.unique=nil + data.shared=nil + savedataincache(container.writable,name,data,fast) + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","save",container.subcategory,name) + end + data.unique=unique + data.shared=shared + end + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","store",container.subcategory,name) + end + container.storage[name]=data + end + return data +end +function containers.content(container,name) + return container.storage[name] +end +function containers.cleanname(name) + return (gsub(lower(name),"[^%w\128-\255]+","-")) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod” 4b5c3c63e19df1b3f37fae7f87c25bda] --- + +if not modules then modules={} end modules ['luatex-fonts-nod']={ + version=1.001, + comment="companion to luatex-fonts.lua", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +if tex.attribute[0]~=0 then + texio.write_nl("log","!") + texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") + texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") + texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") + texio.write_nl("log","!") + tex.attribute[0]=0 +end +attributes=attributes or {} +attributes.unsetvalue=-0x7FFFFFFF +local numbers,last={},127 +attributes.private=attributes.private or function(name) + local number=numbers[name] + if not number then + if last<255 then + last=last+1 + end + number=last + numbers[name]=number + end + return number +end +nodes={} +nodes.handlers={} +local nodecodes={} +local glyphcodes=node.subtypes("glyph") +local disccodes=node.subtypes("disc") +for k,v in next,node.types() do + v=string.gsub(v,"_","") + nodecodes[k]=v + nodecodes[v]=k +end +for k,v in next,glyphcodes do + glyphcodes[v]=k +end +for k,v in next,disccodes do + disccodes[v]=k +end +nodes.nodecodes=nodecodes +nodes.glyphcodes=glyphcodes +nodes.disccodes=disccodes +nodes.dirvalues={ lefttoright=0,righttoleft=1 } +nodes.handlers.protectglyphs=node.protect_glyphs +nodes.handlers.unprotectglyphs=node.unprotect_glyphs +local direct=node.direct +local nuts={} +nodes.nuts=nuts +local tonode=direct.tonode +local tonut=direct.todirect +nodes.tonode=tonode +nodes.tonut=tonut +nuts.tonode=tonode +nuts.tonut=tonut +nuts.getattr=direct.get_attribute +nuts.getboth=direct.getboth +nuts.getchar=direct.getchar +nuts.getdirection=direct.getdirection +nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace +nuts.getfield=direct.getfield +nuts.getfont=direct.getfont +nuts.getid=direct.getid +nuts.getkern=direct.getkern +nuts.getlist=direct.getlist +nuts.getnext=direct.getnext +nuts.getoffsets=direct.getoffsets +nuts.getoptions=direct.getoptions or function() return 0 end +nuts.getprev=direct.getprev +nuts.getsubtype=direct.getsubtype +nuts.getwidth=direct.getwidth +nuts.setattr=direct.setfield +nuts.setboth=direct.setboth +nuts.setchar=direct.setchar +nuts.setcomponents=direct.setcomponents +nuts.setdirection=direct.setdirection +nuts.setdisc=direct.setdisc +nuts.setreplace=direct.setreplace +nuts.setfield=setfield +nuts.setkern=direct.setkern +nuts.setlink=direct.setlink +nuts.setlist=direct.setlist +nuts.setnext=direct.setnext +nuts.setoffsets=direct.setoffsets +nuts.setprev=direct.setprev +nuts.setsplit=direct.setsplit +nuts.setsubtype=direct.setsubtype +nuts.setwidth=direct.setwidth +nuts.getglyphdata=nuts.getattr +nuts.setglyphdata=nuts.setattr +nuts.ischar=direct.is_char +nuts.isglyph=direct.is_glyph +nuts.copy=direct.copy +nuts.copy_list=direct.copy_list +nuts.copy_node=direct.copy +nuts.end_of_math=direct.end_of_math +nuts.flush=direct.flush +nuts.flush_list=direct.flush_list +nuts.flush_node=direct.flush_node +nuts.free=direct.free +nuts.insert_after=direct.insert_after +nuts.insert_before=direct.insert_before +nuts.is_node=direct.is_node +nuts.kerning=direct.kerning +nuts.ligaturing=direct.ligaturing +nuts.new=direct.new +nuts.remove=direct.remove +nuts.tail=direct.tail +nuts.traverse=direct.traverse +nuts.traverse_char=direct.traverse_char +nuts.traverse_glyph=direct.traverse_glyph +nuts.traverse_id=direct.traverse_id +local propertydata=direct.get_properties_table() +nodes.properties={ data=propertydata } +if direct.set_properties_mode then + direct.set_properties_mode(true,true) + function direct.set_properties_mode() end +end +nuts.getprop=function(n,k) + local p=propertydata[n] + if p then + return p[k] + end +end +nuts.setprop=function(n,k,v) + if v then + local p=propertydata[n] + if p then + p[k]=v + else + propertydata[n]={ [k]=v } + end + end +end +nodes.setprop=nodes.setproperty +nodes.getprop=nodes.getproperty +local setprev=nuts.setprev +local setnext=nuts.setnext +local getnext=nuts.getnext +local setlink=nuts.setlink +local getfield=nuts.getfield +local setfield=nuts.setfield +local getsubtype=nuts.getsubtype +local isglyph=nuts.isglyph +local find_tail=nuts.tail +local flush_list=nuts.flush_list +local flush_node=nuts.flush_node +local traverse_id=nuts.traverse_id +local copy_node=nuts.copy_node +local glyph_code=nodes.nodecodes.glyph +local ligature_code=nodes.glyphcodes.ligature +do + local p=nodecodes.localpar or nodecodes.local_par + if p then + nodecodes.par=p + nodecodes[p]="par" + nodecodes.localpar=p + nodecodes.local_par=p + end +end +do + local get_components=node.direct.getcomponents + local set_components=node.direct.setcomponents + local function copy_no_components(g,copyinjection) + local components=get_components(g) + if components then + set_components(g) + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + set_components(g,components) + return n + else + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + return n + end + end + local function copy_only_glyphs(current) + local head=nil + local previous=nil + for n in traverse_id(glyph_code,current) do + n=copy_node(n) + if head then + setlink(previous,n) + else + head=n + end + previous=n + end + return head + end + local function count_components(start,marks) + local char=isglyph(start) + if char then + if getsubtype(start)==ligature_code then + local n=0 + local components=get_components(start) + while components do + n=n+count_components(components,marks) + components=getnext(components) + end + return n + elseif not marks[char] then + return 1 + end + end + return 0 + end + local function flush_components() + end + nuts.set_components=set_components + nuts.get_components=get_components + nuts.copy_only_glyphs=copy_only_glyphs + nuts.copy_no_components=copy_no_components + nuts.count_components=count_components + nuts.flush_components=flush_components +end +nuts.uses_font=direct.uses_font +do + local dummy=tonut(node.new("glyph")) + nuts.traversers={ + glyph=nuts.traverse_id(nodecodes.glyph,dummy), + glue=nuts.traverse_id(nodecodes.glue,dummy), + disc=nuts.traverse_id(nodecodes.disc,dummy), + boundary=nuts.traverse_id(nodecodes.boundary,dummy), + char=nuts.traverse_char(dummy), + node=nuts.traverse(dummy), + } +end +if not nuts.setreplace then + local getdisc=nuts.getdisc + local setfield=nuts.setfield + function nuts.getreplace(n) + local _,_,h,_,_,t=getdisc(n,true) + return h,t + end + function nuts.setreplace(n,h) + setfield(n,"replace",h) + end +end +do + local getsubtype=nuts.getsubtype + function nuts.start_of_par(n) + local s=getsubtype(n) + return s==0 or s==2 + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr” 64fafe4eaf55d64aead6513c1e74a024] --- + + +characters=characters or {} +characters.blockrange={} +characters.classifiers={ + [768]=5, + [769]=5, + [770]=5, + [771]=5, + [772]=5, + [773]=5, + [774]=5, + [775]=5, + [776]=5, + [777]=5, + [778]=5, + [779]=5, + [780]=5, + [781]=5, + [782]=5, + [783]=5, + [784]=5, + [785]=5, + [786]=5, + [787]=5, + [788]=5, + [789]=5, + [790]=5, + [791]=5, + [792]=5, + [793]=5, + [794]=5, + [795]=5, + [796]=5, + [797]=5, + [798]=5, + [799]=5, + [800]=5, + [801]=5, + [802]=5, + [803]=5, + [804]=5, + [805]=5, + [806]=5, + [807]=5, + [808]=5, + [809]=5, + [810]=5, + [811]=5, + [812]=5, + [813]=5, + [814]=5, + [815]=5, + [816]=5, + [817]=5, + [818]=5, + [819]=5, + [820]=5, + [821]=5, + [822]=5, + [823]=5, + [824]=5, + [825]=5, + [826]=5, + [827]=5, + [828]=5, + [829]=5, + [830]=5, + [831]=5, + [832]=5, + [833]=5, + [834]=5, + [835]=5, + [836]=5, + [837]=5, + [838]=5, + [839]=5, + [840]=5, + [841]=5, + [842]=5, + [843]=5, + [844]=5, + [845]=5, + [846]=5, + [847]=5, + [848]=5, + [849]=5, + [850]=5, + [851]=5, + [852]=5, + [853]=5, + [854]=5, + [855]=5, + [856]=5, + [857]=5, + [858]=5, + [859]=5, + [860]=5, + [861]=5, + [862]=5, + [863]=5, + [864]=5, + [865]=5, + [866]=5, + [867]=5, + [868]=5, + [869]=5, + [870]=5, + [871]=5, + [872]=5, + [873]=5, + [874]=5, + [875]=5, + [876]=5, + [877]=5, + [878]=5, + [879]=5, + [1155]=5, + [1156]=5, + [1157]=5, + [1158]=5, + [1159]=5, + [1425]=5, + [1426]=5, + [1427]=5, + [1428]=5, + [1429]=5, + [1430]=5, + [1431]=5, + [1432]=5, + [1433]=5, + [1434]=5, + [1435]=5, + [1436]=5, + [1437]=5, + [1438]=5, + [1439]=5, + [1440]=5, + [1441]=5, + [1442]=5, + [1443]=5, + [1444]=5, + [1445]=5, + [1446]=5, + [1447]=5, + [1448]=5, + [1449]=5, + [1450]=5, + [1451]=5, + [1452]=5, + [1453]=5, + [1454]=5, + [1455]=5, + [1456]=5, + [1457]=5, + [1458]=5, + [1459]=5, + [1460]=5, + [1461]=5, + [1462]=5, + [1463]=5, + [1464]=5, + [1465]=5, + [1466]=5, + [1467]=5, + [1468]=5, + [1469]=5, + [1471]=5, + [1473]=5, + [1474]=5, + [1476]=5, + [1477]=5, + [1479]=5, + [1536]=4, + [1537]=4, + [1538]=4, + [1539]=4, + [1540]=4, + [1541]=4, + [1542]=6, + [1543]=6, + [1544]=4, + [1545]=6, + [1546]=6, + [1547]=4, + [1548]=6, + [1549]=6, + [1550]=6, + [1551]=6, + [1552]=5, + [1553]=5, + [1554]=5, + [1555]=5, + [1556]=5, + [1557]=5, + [1558]=5, + [1559]=5, + [1560]=5, + [1561]=5, + [1562]=5, + [1563]=6, + [1564]=6, + [1566]=6, + [1567]=6, + [1568]=2, + [1569]=4, + [1570]=3, + [1571]=3, + [1572]=3, + [1573]=3, + [1574]=2, + [1575]=3, + [1576]=2, + [1577]=3, + [1578]=2, + [1579]=2, + [1580]=2, + [1581]=2, + [1582]=2, + [1583]=3, + [1584]=3, + [1585]=3, + [1586]=3, + [1587]=2, + [1588]=2, + [1589]=2, + [1590]=2, + [1591]=2, + [1592]=2, + [1593]=2, + [1594]=2, + [1595]=2, + [1596]=2, + [1597]=2, + [1598]=2, + [1599]=2, + [1600]=2, + [1601]=2, + [1602]=2, + [1603]=2, + [1604]=2, + [1605]=2, + [1606]=2, + [1607]=2, + [1608]=3, + [1609]=2, + [1610]=2, + [1611]=5, + [1612]=5, + [1613]=5, + [1614]=5, + [1615]=5, + [1616]=5, + [1617]=5, + [1618]=5, + [1619]=5, + [1620]=5, + [1621]=5, + [1622]=5, + [1623]=5, + [1624]=5, + [1625]=5, + [1626]=5, + [1627]=5, + [1628]=5, + [1629]=5, + [1630]=5, + [1631]=5, + [1632]=6, + [1633]=6, + [1634]=6, + [1635]=6, + [1636]=6, + [1637]=6, + [1638]=6, + [1639]=6, + [1640]=6, + [1641]=6, + [1642]=6, + [1643]=6, + [1644]=6, + [1645]=6, + [1646]=2, + [1647]=2, + [1648]=5, + [1649]=3, + [1650]=3, + [1651]=3, + [1652]=4, + [1653]=3, + [1654]=3, + [1655]=3, + [1656]=2, + [1657]=2, + [1658]=2, + [1659]=2, + [1660]=2, + [1661]=2, + [1662]=2, + [1663]=2, + [1664]=2, + [1665]=2, + [1666]=2, + [1667]=2, + [1668]=2, + [1669]=2, + [1670]=2, + [1671]=2, + [1672]=3, + [1673]=3, + [1674]=3, + [1675]=3, + [1676]=3, + [1677]=3, + [1678]=3, + [1679]=3, + [1680]=3, + [1681]=3, + [1682]=3, + [1683]=3, + [1684]=3, + [1685]=3, + [1686]=3, + [1687]=3, + [1688]=3, + [1689]=3, + [1690]=2, + [1691]=2, + [1692]=2, + [1693]=2, + [1694]=2, + [1695]=2, + [1696]=2, + [1697]=2, + [1698]=2, + [1699]=2, + [1700]=2, + [1701]=2, + [1702]=2, + [1703]=2, + [1704]=2, + [1705]=2, + [1706]=2, + [1707]=2, + [1708]=2, + [1709]=2, + [1710]=2, + [1711]=2, + [1712]=2, + [1713]=2, + [1714]=2, + [1715]=2, + [1716]=2, + [1717]=2, + [1718]=2, + [1719]=2, + [1720]=2, + [1721]=2, + [1722]=2, + [1723]=2, + [1724]=2, + [1725]=2, + [1726]=2, + [1727]=2, + [1728]=3, + [1729]=2, + [1730]=2, + [1731]=3, + [1732]=3, + [1733]=3, + [1734]=3, + [1735]=3, + [1736]=3, + [1737]=3, + [1738]=3, + [1739]=3, + [1740]=2, + [1741]=3, + [1742]=2, + [1743]=3, + [1744]=2, + [1745]=2, + [1746]=3, + [1747]=3, + [1748]=6, + [1749]=3, + [1750]=5, + [1751]=5, + [1752]=5, + [1753]=5, + [1754]=5, + [1755]=5, + [1756]=5, + [1757]=4, + [1758]=6, + [1759]=5, + [1760]=5, + [1761]=5, + [1762]=5, + [1763]=5, + [1764]=5, + [1765]=6, + [1766]=6, + [1767]=5, + [1768]=5, + [1769]=6, + [1770]=5, + [1771]=5, + [1772]=5, + [1773]=5, + [1774]=3, + [1775]=3, + [1776]=6, + [1777]=6, + [1778]=6, + [1779]=6, + [1780]=6, + [1781]=6, + [1782]=6, + [1783]=6, + [1784]=6, + [1785]=6, + [1786]=2, + [1787]=2, + [1788]=2, + [1789]=6, + [1790]=6, + [1791]=2, + [1792]=6, + [1793]=6, + [1794]=6, + [1795]=6, + [1796]=6, + [1797]=6, + [1798]=6, + [1799]=6, + [1800]=6, + [1801]=6, + [1802]=6, + [1803]=6, + [1804]=6, + [1805]=6, + [1808]=3, + [1809]=5, + [1810]=2, + [1811]=2, + [1812]=2, + [1813]=3, + [1814]=3, + [1815]=3, + [1816]=3, + [1817]=3, + [1818]=2, + [1819]=2, + [1820]=2, + [1821]=2, + [1822]=3, + [1823]=2, + [1824]=2, + [1825]=2, + [1826]=2, + [1827]=2, + [1828]=2, + [1829]=2, + [1830]=2, + [1831]=2, + [1832]=3, + [1833]=2, + [1834]=3, + [1835]=2, + [1836]=3, + [1837]=2, + [1838]=2, + [1839]=3, + [1840]=5, + [1841]=5, + [1842]=5, + [1843]=5, + [1844]=5, + [1845]=5, + [1846]=5, + [1847]=5, + [1848]=5, + [1849]=5, + [1850]=5, + [1851]=5, + [1852]=5, + [1853]=5, + [1854]=5, + [1855]=5, + [1856]=5, + [1857]=5, + [1858]=5, + [1859]=5, + [1860]=5, + [1861]=5, + [1862]=5, + [1863]=5, + [1864]=5, + [1865]=5, + [1866]=5, + [1869]=3, + [1870]=2, + [1871]=2, + [1872]=2, + [1873]=2, + [1874]=2, + [1875]=2, + [1876]=2, + [1877]=2, + [1878]=2, + [1879]=2, + [1880]=2, + [1881]=3, + [1882]=3, + [1883]=3, + [1884]=2, + [1885]=2, + [1886]=2, + [1887]=2, + [1888]=2, + [1889]=2, + [1890]=2, + [1891]=2, + [1892]=2, + [1893]=2, + [1894]=2, + [1895]=2, + [1896]=2, + [1897]=2, + [1898]=2, + [1899]=3, + [1900]=3, + [1901]=2, + [1902]=2, + [1903]=2, + [1904]=2, + [1905]=3, + [1906]=2, + [1907]=3, + [1908]=3, + [1909]=2, + [1910]=2, + [1911]=2, + [1912]=3, + [1913]=3, + [1914]=2, + [1915]=2, + [1916]=2, + [1917]=2, + [1918]=2, + [1919]=2, + [1958]=5, + [1959]=5, + [1960]=5, + [1961]=5, + [1962]=5, + [1963]=5, + [1964]=5, + [1965]=5, + [1966]=5, + [1967]=5, + [1968]=5, + [1984]=6, + [1985]=6, + [1986]=6, + [1987]=6, + [1988]=6, + [1989]=6, + [1990]=6, + [1991]=6, + [1992]=6, + [1993]=6, + [1994]=2, + [1995]=2, + [1996]=2, + [1997]=2, + [1998]=2, + [1999]=2, + [2000]=2, + [2001]=2, + [2002]=2, + [2003]=2, + [2004]=2, + [2005]=2, + [2006]=2, + [2007]=2, + [2008]=2, + [2009]=2, + [2010]=2, + [2011]=2, + [2012]=2, + [2013]=2, + [2014]=2, + [2015]=2, + [2016]=2, + [2017]=2, + [2018]=2, + [2019]=2, + [2020]=2, + [2021]=2, + [2022]=2, + [2023]=2, + [2024]=2, + [2025]=2, + [2026]=2, + [2027]=5, + [2028]=5, + [2029]=5, + [2030]=5, + [2031]=5, + [2032]=5, + [2033]=5, + [2034]=5, + [2035]=5, + [2036]=6, + [2037]=6, + [2038]=6, + [2039]=6, + [2040]=6, + [2041]=6, + [2042]=2, + [2045]=5, + [2046]=6, + [2047]=6, + [2070]=5, + [2071]=5, + [2072]=5, + [2073]=5, + [2075]=5, + [2076]=5, + [2077]=5, + [2078]=5, + [2079]=5, + [2080]=5, + [2081]=5, + [2082]=5, + [2083]=5, + [2085]=5, + [2086]=5, + [2087]=5, + [2089]=5, + [2090]=5, + [2091]=5, + [2092]=5, + [2093]=5, + [2112]=3, + [2113]=2, + [2114]=2, + [2115]=2, + [2116]=2, + [2117]=2, + [2118]=3, + [2119]=3, + [2120]=2, + [2121]=3, + [2122]=2, + [2123]=2, + [2124]=2, + [2125]=2, + [2126]=2, + [2127]=2, + [2128]=2, + [2129]=2, + [2130]=2, + [2131]=2, + [2132]=3, + [2133]=2, + [2134]=4, + [2135]=4, + [2136]=4, + [2137]=5, + [2138]=5, + [2139]=5, + [2144]=2, + [2145]=4, + [2146]=2, + [2147]=2, + [2148]=2, + [2149]=2, + [2150]=4, + [2151]=3, + [2152]=2, + [2153]=3, + [2154]=3, + [2208]=2, + [2209]=2, + [2210]=2, + [2211]=2, + [2212]=2, + [2213]=2, + [2214]=2, + [2215]=2, + [2216]=2, + [2217]=2, + [2218]=3, + [2219]=3, + [2220]=3, + [2221]=4, + [2222]=3, + [2223]=2, + [2224]=2, + [2225]=3, + [2226]=3, + [2227]=2, + [2228]=2, + [2230]=2, + [2231]=2, + [2232]=2, + [2233]=3, + [2234]=2, + [2235]=2, + [2236]=2, + [2237]=2, + [2259]=5, + [2260]=5, + [2261]=5, + [2262]=5, + [2263]=5, + [2264]=5, + [2265]=5, + [2266]=5, + [2267]=5, + [2268]=5, + [2269]=5, + [2270]=5, + [2271]=5, + [2272]=5, + [2273]=5, + [2274]=4, + [2275]=5, + [2276]=5, + [2277]=5, + [2278]=5, + [2279]=5, + [2280]=5, + [2281]=5, + [2282]=5, + [2283]=5, + [2284]=5, + [2285]=5, + [2286]=5, + [2287]=5, + [2288]=5, + [2289]=5, + [2290]=5, + [2291]=5, + [2292]=5, + [2293]=5, + [2294]=5, + [2295]=5, + [2296]=5, + [2297]=5, + [2298]=5, + [2299]=5, + [2300]=5, + [2301]=5, + [2302]=5, + [2303]=5, + [2304]=5, + [2305]=5, + [2306]=5, + [2362]=5, + [2364]=5, + [2369]=5, + [2370]=5, + [2371]=5, + [2372]=5, + [2373]=5, + [2374]=5, + [2375]=5, + [2376]=5, + [2381]=5, + [2385]=5, + [2386]=5, + [2387]=5, + [2388]=5, + [2389]=5, + [2390]=5, + [2391]=5, + [2402]=5, + [2403]=5, + [2433]=5, + [2492]=5, + [2497]=5, + [2498]=5, + [2499]=5, + [2500]=5, + [2509]=5, + [2530]=5, + [2531]=5, + [2558]=5, + [2561]=5, + [2562]=5, + [2620]=5, + [2625]=5, + [2626]=5, + [2631]=5, + [2632]=5, + [2635]=5, + [2636]=5, + [2637]=5, + [2641]=5, + [2672]=5, + [2673]=5, + [2677]=5, + [2689]=5, + [2690]=5, + [2748]=5, + [2753]=5, + [2754]=5, + [2755]=5, + [2756]=5, + [2757]=5, + [2759]=5, + [2760]=5, + [2765]=5, + [2786]=5, + [2787]=5, + [2810]=5, + [2811]=5, + [2812]=5, + [2813]=5, + [2814]=5, + [2815]=5, + [2817]=5, + [2876]=5, + [2879]=5, + [2881]=5, + [2882]=5, + [2883]=5, + [2884]=5, + [2893]=5, + [2902]=5, + [2914]=5, + [2915]=5, + [2946]=5, + [3008]=5, + [3021]=5, + [3072]=5, + [3076]=5, + [3134]=5, + [3135]=5, + [3136]=5, + [3142]=5, + [3143]=5, + [3144]=5, + [3146]=5, + [3147]=5, + [3148]=5, + [3149]=5, + [3157]=5, + [3158]=5, + [3170]=5, + [3171]=5, + [3201]=5, + [3260]=5, + [3263]=5, + [3270]=5, + [3276]=5, + [3277]=5, + [3298]=5, + [3299]=5, + [3328]=5, + [3329]=5, + [3387]=5, + [3388]=5, + [3393]=5, + [3394]=5, + [3395]=5, + [3396]=5, + [3405]=5, + [3426]=5, + [3427]=5, + [3530]=5, + [3538]=5, + [3539]=5, + [3540]=5, + [3542]=5, + [3633]=5, + [3636]=5, + [3637]=5, + [3638]=5, + [3639]=5, + [3640]=5, + [3641]=5, + [3642]=5, + [3655]=5, + [3656]=5, + [3657]=5, + [3658]=5, + [3659]=5, + [3660]=5, + [3661]=5, + [3662]=5, + [3761]=5, + [3764]=5, + [3765]=5, + [3766]=5, + [3767]=5, + [3768]=5, + [3769]=5, + [3770]=5, + [3771]=5, + [3772]=5, + [3784]=5, + [3785]=5, + [3786]=5, + [3787]=5, + [3788]=5, + [3789]=5, + [3864]=5, + [3865]=5, + [3893]=5, + [3895]=5, + [3897]=5, + [3953]=5, + [3954]=5, + [3955]=5, + [3956]=5, + [3957]=5, + [3958]=5, + [3959]=5, + [3960]=5, + [3961]=5, + [3962]=5, + [3963]=5, + [3964]=5, + [3965]=5, + [3966]=5, + [3968]=5, + [3969]=5, + [3970]=5, + [3971]=5, + [3972]=5, + [3974]=5, + [3975]=5, + [3981]=5, + [3982]=5, + [3983]=5, + [3984]=5, + [3985]=5, + [3986]=5, + [3987]=5, + [3988]=5, + [3989]=5, + [3990]=5, + [3991]=5, + [3993]=5, + [3994]=5, + [3995]=5, + [3996]=5, + [3997]=5, + [3998]=5, + [3999]=5, + [4000]=5, + [4001]=5, + [4002]=5, + [4003]=5, + [4004]=5, + [4005]=5, + [4006]=5, + [4007]=5, + [4008]=5, + [4009]=5, + [4010]=5, + [4011]=5, + [4012]=5, + [4013]=5, + [4014]=5, + [4015]=5, + [4016]=5, + [4017]=5, + [4018]=5, + [4019]=5, + [4020]=5, + [4021]=5, + [4022]=5, + [4023]=5, + [4024]=5, + [4025]=5, + [4026]=5, + [4027]=5, + [4028]=5, + [4038]=5, + [4141]=5, + [4142]=5, + [4143]=5, + [4144]=5, + [4146]=5, + [4147]=5, + [4148]=5, + [4149]=5, + [4150]=5, + [4151]=5, + [4153]=5, + [4154]=5, + [4157]=5, + [4158]=5, + [4184]=5, + [4185]=5, + [4190]=5, + [4191]=5, + [4192]=5, + [4209]=5, + [4210]=5, + [4211]=5, + [4212]=5, + [4226]=5, + [4229]=5, + [4230]=5, + [4237]=5, + [4253]=5, + [4957]=5, + [4958]=5, + [4959]=5, + [5906]=5, + [5907]=5, + [5908]=5, + [5938]=5, + [5939]=5, + [5940]=5, + [5970]=5, + [5971]=5, + [6002]=5, + [6003]=5, + [6071]=5, + [6072]=5, + [6073]=5, + [6074]=5, + [6075]=5, + [6076]=5, + [6077]=5, + [6086]=5, + [6089]=5, + [6090]=5, + [6091]=5, + [6092]=5, + [6093]=5, + [6094]=5, + [6095]=5, + [6096]=5, + [6097]=5, + [6098]=5, + [6099]=5, + [6109]=5, + [6150]=4, + [6151]=2, + [6154]=2, + [6155]=5, + [6156]=5, + [6157]=5, + [6158]=4, + [6176]=2, + [6177]=2, + [6178]=2, + [6179]=2, + [6180]=2, + [6181]=2, + [6182]=2, + [6183]=2, + [6184]=2, + [6185]=2, + [6186]=2, + [6187]=2, + [6188]=2, + [6189]=2, + [6190]=2, + [6191]=2, + [6192]=2, + [6193]=2, + [6194]=2, + [6195]=2, + [6196]=2, + [6197]=2, + [6198]=2, + [6199]=2, + [6200]=2, + [6201]=2, + [6202]=2, + [6203]=2, + [6204]=2, + [6205]=2, + [6206]=2, + [6207]=2, + [6208]=2, + [6209]=2, + [6210]=2, + [6211]=2, + [6212]=2, + [6213]=2, + [6214]=2, + [6215]=2, + [6216]=2, + [6217]=2, + [6218]=2, + [6219]=2, + [6220]=2, + [6221]=2, + [6222]=2, + [6223]=2, + [6224]=2, + [6225]=2, + [6226]=2, + [6227]=2, + [6228]=2, + [6229]=2, + [6230]=2, + [6231]=2, + [6232]=2, + [6233]=2, + [6234]=2, + [6235]=2, + [6236]=2, + [6237]=2, + [6238]=2, + [6239]=2, + [6240]=2, + [6241]=2, + [6242]=2, + [6243]=2, + [6244]=2, + [6245]=2, + [6246]=2, + [6247]=2, + [6248]=2, + [6249]=2, + [6250]=2, + [6251]=2, + [6252]=2, + [6253]=2, + [6254]=2, + [6255]=2, + [6256]=2, + [6257]=2, + [6258]=2, + [6259]=2, + [6260]=2, + [6261]=2, + [6262]=2, + [6263]=2, + [6264]=2, + [6272]=4, + [6273]=4, + [6274]=4, + [6275]=4, + [6276]=4, + [6279]=2, + [6280]=2, + [6281]=2, + [6282]=2, + [6283]=2, + [6284]=2, + [6285]=2, + [6286]=2, + [6287]=2, + [6288]=2, + [6289]=2, + [6290]=2, + [6291]=2, + [6292]=2, + [6293]=2, + [6294]=2, + [6295]=2, + [6296]=2, + [6297]=2, + [6298]=2, + [6299]=2, + [6300]=2, + [6301]=2, + [6302]=2, + [6303]=2, + [6304]=2, + [6305]=2, + [6306]=2, + [6307]=2, + [6308]=2, + [6309]=2, + [6310]=2, + [6311]=2, + [6312]=2, + [6313]=5, + [6314]=2, + [6432]=5, + [6433]=5, + [6434]=5, + [6439]=5, + [6440]=5, + [6450]=5, + [6457]=5, + [6458]=5, + [6459]=5, + [6679]=5, + [6680]=5, + [6742]=5, + [6744]=5, + [6745]=5, + [6746]=5, + [6747]=5, + [6748]=5, + [6749]=5, + [6750]=5, + [6752]=5, + [6754]=5, + [6757]=5, + [6758]=5, + [6759]=5, + [6760]=5, + [6761]=5, + [6762]=5, + [6763]=5, + [6764]=5, + [6771]=5, + [6772]=5, + [6773]=5, + [6774]=5, + [6775]=5, + [6776]=5, + [6777]=5, + [6778]=5, + [6779]=5, + [6780]=5, + [6783]=5, + [6832]=5, + [6833]=5, + [6834]=5, + [6835]=5, + [6836]=5, + [6837]=5, + [6838]=5, + [6839]=5, + [6840]=5, + [6841]=5, + [6842]=5, + [6843]=5, + [6844]=5, + [6845]=5, + [6912]=5, + [6913]=5, + [6914]=5, + [6915]=5, + [6964]=5, + [6966]=5, + [6967]=5, + [6968]=5, + [6969]=5, + [6970]=5, + [6972]=5, + [6978]=5, + [7019]=5, + [7020]=5, + [7021]=5, + [7022]=5, + [7023]=5, + [7024]=5, + [7025]=5, + [7026]=5, + [7027]=5, + [7040]=5, + [7041]=5, + [7074]=5, + [7075]=5, + [7076]=5, + [7077]=5, + [7080]=5, + [7081]=5, + [7083]=5, + [7142]=5, + [7144]=5, + [7145]=5, + [7149]=5, + [7151]=5, + [7152]=5, + [7153]=5, + [7212]=5, + [7213]=5, + [7214]=5, + [7215]=5, + [7216]=5, + [7217]=5, + [7218]=5, + [7219]=5, + [7222]=5, + [7223]=5, + [7376]=5, + [7377]=5, + [7378]=5, + [7380]=5, + [7381]=5, + [7382]=5, + [7383]=5, + [7384]=5, + [7385]=5, + [7386]=5, + [7387]=5, + [7388]=5, + [7389]=5, + [7390]=5, + [7391]=5, + [7392]=5, + [7394]=5, + [7395]=5, + [7396]=5, + [7397]=5, + [7398]=5, + [7399]=5, + [7400]=5, + [7405]=5, + [7412]=5, + [7416]=5, + [7417]=5, + [7616]=5, + [7617]=5, + [7618]=5, + [7619]=5, + [7620]=5, + [7621]=5, + [7622]=5, + [7623]=5, + [7624]=5, + [7625]=5, + [7626]=5, + [7627]=5, + [7628]=5, + [7629]=5, + [7630]=5, + [7631]=5, + [7632]=5, + [7633]=5, + [7634]=5, + [7635]=5, + [7636]=5, + [7637]=5, + [7638]=5, + [7639]=5, + [7640]=5, + [7641]=5, + [7642]=5, + [7643]=5, + [7644]=5, + [7645]=5, + [7646]=5, + [7647]=5, + [7648]=5, + [7649]=5, + [7650]=5, + [7651]=5, + [7652]=5, + [7653]=5, + [7654]=5, + [7655]=5, + [7656]=5, + [7657]=5, + [7658]=5, + [7659]=5, + [7660]=5, + [7661]=5, + [7662]=5, + [7663]=5, + [7664]=5, + [7665]=5, + [7666]=5, + [7667]=5, + [7668]=5, + [7669]=5, + [7670]=5, + [7671]=5, + [7672]=5, + [7673]=5, + [7675]=5, + [7676]=5, + [7677]=5, + [7678]=5, + [7679]=5, + [8204]=4, + [8205]=2, + [8239]=4, + [8294]=4, + [8295]=4, + [8296]=4, + [8297]=4, + [8400]=5, + [8401]=5, + [8402]=5, + [8403]=5, + [8404]=5, + [8405]=5, + [8406]=5, + [8407]=5, + [8408]=5, + [8409]=5, + [8410]=5, + [8411]=5, + [8412]=5, + [8417]=5, + [8421]=5, + [8422]=5, + [8423]=5, + [8424]=5, + [8425]=5, + [8426]=5, + [8427]=5, + [8428]=5, + [8429]=5, + [8430]=5, + [8431]=5, + [8432]=5, + [11503]=5, + [11504]=5, + [11505]=5, + [11647]=5, + [11744]=5, + [11745]=5, + [11746]=5, + [11747]=5, + [11748]=5, + [11749]=5, + [11750]=5, + [11751]=5, + [11752]=5, + [11753]=5, + [11754]=5, + [11755]=5, + [11756]=5, + [11757]=5, + [11758]=5, + [11759]=5, + [11760]=5, + [11761]=5, + [11762]=5, + [11763]=5, + [11764]=5, + [11765]=5, + [11766]=5, + [11767]=5, + [11768]=5, + [11769]=5, + [11770]=5, + [11771]=5, + [11772]=5, + [11773]=5, + [11774]=5, + [11775]=5, + [12330]=5, + [12331]=5, + [12332]=5, + [12333]=5, + [12334]=5, + [12335]=5, + [12441]=5, + [12442]=5, + [42607]=5, + [42612]=5, + [42613]=5, + [42614]=5, + [42615]=5, + [42616]=5, + [42617]=5, + [42618]=5, + [42619]=5, + [42620]=5, + [42621]=5, + [42654]=5, + [42655]=5, + [42736]=5, + [42737]=5, + [43014]=5, + [43019]=5, + [43045]=5, + [43046]=5, + [43072]=2, + [43073]=2, + [43074]=2, + [43075]=2, + [43076]=2, + [43077]=2, + [43078]=2, + [43079]=2, + [43080]=2, + [43081]=2, + [43082]=2, + [43083]=2, + [43084]=2, + [43085]=2, + [43086]=2, + [43087]=2, + [43088]=2, + [43089]=2, + [43090]=2, + [43091]=2, + [43092]=2, + [43093]=2, + [43094]=2, + [43095]=2, + [43096]=2, + [43097]=2, + [43098]=2, + [43099]=2, + [43100]=2, + [43101]=2, + [43102]=2, + [43103]=2, + [43104]=2, + [43105]=2, + [43106]=2, + [43107]=2, + [43108]=2, + [43109]=2, + [43110]=2, + [43111]=2, + [43112]=2, + [43113]=2, + [43114]=2, + [43115]=2, + [43116]=2, + [43117]=2, + [43118]=2, + [43119]=2, + [43120]=2, + [43121]=2, + [43122]=1, + [43123]=4, + [43204]=5, + [43205]=5, + [43232]=5, + [43233]=5, + [43234]=5, + [43235]=5, + [43236]=5, + [43237]=5, + [43238]=5, + [43239]=5, + [43240]=5, + [43241]=5, + [43242]=5, + [43243]=5, + [43244]=5, + [43245]=5, + [43246]=5, + [43247]=5, + [43248]=5, + [43249]=5, + [43263]=5, + [43302]=5, + [43303]=5, + [43304]=5, + [43305]=5, + [43306]=5, + [43307]=5, + [43308]=5, + [43309]=5, + [43335]=5, + [43336]=5, + [43337]=5, + [43338]=5, + [43339]=5, + [43340]=5, + [43341]=5, + [43342]=5, + [43343]=5, + [43344]=5, + [43345]=5, + [43392]=5, + [43393]=5, + [43394]=5, + [43443]=5, + [43446]=5, + [43447]=5, + [43448]=5, + [43449]=5, + [43452]=5, + [43493]=5, + [43561]=5, + [43562]=5, + [43563]=5, + [43564]=5, + [43565]=5, + [43566]=5, + [43569]=5, + [43570]=5, + [43573]=5, + [43574]=5, + [43587]=5, + [43596]=5, + [43644]=5, + [43696]=5, + [43698]=5, + [43699]=5, + [43700]=5, + [43703]=5, + [43704]=5, + [43710]=5, + [43711]=5, + [43713]=5, + [43756]=5, + [43757]=5, + [43766]=5, + [44005]=5, + [44008]=5, + [44013]=5, + [64286]=5, + [65056]=5, + [65057]=5, + [65058]=5, + [65059]=5, + [65060]=5, + [65061]=5, + [65062]=5, + [65063]=5, + [65064]=5, + [65065]=5, + [65066]=5, + [65067]=5, + [65068]=5, + [65069]=5, + [65070]=5, + [65071]=5, + [66045]=5, + [66272]=5, + [66422]=5, + [66423]=5, + [66424]=5, + [66425]=5, + [66426]=5, + [68097]=5, + [68098]=5, + [68099]=5, + [68101]=5, + [68102]=5, + [68108]=5, + [68109]=5, + [68110]=5, + [68111]=5, + [68152]=5, + [68153]=5, + [68154]=5, + [68159]=5, + [68288]=2, + [68289]=2, + [68290]=2, + [68291]=2, + [68292]=2, + [68293]=3, + [68294]=4, + [68295]=3, + [68296]=4, + [68297]=3, + [68298]=3, + [68299]=4, + [68300]=4, + [68301]=1, + [68302]=3, + [68303]=3, + [68304]=3, + [68305]=3, + [68306]=3, + [68307]=2, + [68308]=2, + [68309]=2, + [68310]=2, + [68311]=1, + [68312]=2, + [68313]=2, + [68314]=2, + [68315]=2, + [68316]=2, + [68317]=3, + [68318]=2, + [68319]=2, + [68320]=2, + [68321]=3, + [68322]=4, + [68323]=4, + [68324]=3, + [68325]=5, + [68326]=5, + [68331]=2, + [68332]=2, + [68333]=2, + [68334]=2, + [68335]=3, + [68480]=2, + [68481]=3, + [68482]=2, + [68483]=3, + [68484]=3, + [68485]=3, + [68486]=2, + [68487]=2, + [68488]=2, + [68489]=3, + [68490]=2, + [68491]=2, + [68492]=3, + [68493]=2, + [68494]=3, + [68495]=3, + [68496]=2, + [68497]=3, + [68521]=3, + [68522]=3, + [68523]=3, + [68524]=3, + [68525]=2, + [68526]=2, + [68527]=4, + [68864]=1, + [68865]=2, + [68866]=2, + [68867]=2, + [68868]=2, + [68869]=2, + [68870]=2, + [68871]=2, + [68872]=2, + [68873]=2, + [68874]=2, + [68875]=2, + [68876]=2, + [68877]=2, + [68878]=2, + [68879]=2, + [68880]=2, + [68881]=2, + [68882]=2, + [68883]=2, + [68884]=2, + [68885]=2, + [68886]=2, + [68887]=2, + [68888]=2, + [68889]=2, + [68890]=2, + [68891]=2, + [68892]=2, + [68893]=2, + [68894]=2, + [68895]=2, + [68896]=2, + [68897]=2, + [68898]=3, + [68899]=2, + [68900]=5, + [68901]=5, + [68902]=5, + [68903]=5, + [69424]=2, + [69425]=2, + [69426]=2, + [69427]=3, + [69428]=2, + [69429]=2, + [69430]=2, + [69431]=2, + [69432]=2, + [69433]=2, + [69434]=2, + [69435]=2, + [69436]=2, + [69437]=2, + [69438]=2, + [69439]=2, + [69440]=2, + [69441]=2, + [69442]=2, + [69443]=2, + [69444]=2, + [69445]=4, + [69446]=5, + [69447]=5, + [69448]=5, + [69449]=5, + [69450]=5, + [69451]=5, + [69452]=5, + [69453]=5, + [69454]=5, + [69455]=5, + [69456]=5, + [69457]=2, + [69458]=2, + [69459]=2, + [69460]=3, + [69633]=5, + [69688]=5, + [69689]=5, + [69690]=5, + [69691]=5, + [69692]=5, + [69693]=5, + [69694]=5, + [69695]=5, + [69696]=5, + [69697]=5, + [69698]=5, + [69699]=5, + [69700]=5, + [69701]=5, + [69702]=5, + [69759]=5, + [69760]=5, + [69761]=5, + [69811]=5, + [69812]=5, + [69813]=5, + [69814]=5, + [69817]=5, + [69818]=5, + [69821]=4, + [69837]=4, + [69888]=5, + [69889]=5, + [69890]=5, + [69927]=5, + [69928]=5, + [69929]=5, + [69930]=5, + [69931]=5, + [69933]=5, + [69934]=5, + [69935]=5, + [69936]=5, + [69937]=5, + [69938]=5, + [69939]=5, + [69940]=5, + [70003]=5, + [70016]=5, + [70017]=5, + [70070]=5, + [70071]=5, + [70072]=5, + [70073]=5, + [70074]=5, + [70075]=5, + [70076]=5, + [70077]=5, + [70078]=5, + [70090]=5, + [70091]=5, + [70092]=5, + [70191]=5, + [70192]=5, + [70193]=5, + [70196]=5, + [70198]=5, + [70199]=5, + [70206]=5, + [70367]=5, + [70371]=5, + [70372]=5, + [70373]=5, + [70374]=5, + [70375]=5, + [70376]=5, + [70377]=5, + [70378]=5, + [70400]=5, + [70401]=5, + [70459]=5, + [70460]=5, + [70464]=5, + [70502]=5, + [70503]=5, + [70504]=5, + [70505]=5, + [70506]=5, + [70507]=5, + [70508]=5, + [70512]=5, + [70513]=5, + [70514]=5, + [70515]=5, + [70516]=5, + [70712]=5, + [70713]=5, + [70714]=5, + [70715]=5, + [70716]=5, + [70717]=5, + [70718]=5, + [70719]=5, + [70722]=5, + [70723]=5, + [70724]=5, + [70726]=5, + [70750]=5, + [70835]=5, + [70836]=5, + [70837]=5, + [70838]=5, + [70839]=5, + [70840]=5, + [70842]=5, + [70847]=5, + [70848]=5, + [70850]=5, + [70851]=5, + [71090]=5, + [71091]=5, + [71092]=5, + [71093]=5, + [71100]=5, + [71101]=5, + [71103]=5, + [71104]=5, + [71132]=5, + [71133]=5, + [71219]=5, + [71220]=5, + [71221]=5, + [71222]=5, + [71223]=5, + [71224]=5, + [71225]=5, + [71226]=5, + [71229]=5, + [71231]=5, + [71232]=5, + [71339]=5, + [71341]=5, + [71344]=5, + [71345]=5, + [71346]=5, + [71347]=5, + [71348]=5, + [71349]=5, + [71351]=5, + [71453]=5, + [71454]=5, + [71455]=5, + [71458]=5, + [71459]=5, + [71460]=5, + [71461]=5, + [71463]=5, + [71464]=5, + [71465]=5, + [71466]=5, + [71467]=5, + [71727]=5, + [71728]=5, + [71729]=5, + [71730]=5, + [71731]=5, + [71732]=5, + [71733]=5, + [71734]=5, + [71735]=5, + [71737]=5, + [71738]=5, + [72148]=5, + [72149]=5, + [72150]=5, + [72151]=5, + [72154]=5, + [72155]=5, + [72160]=5, + [72193]=5, + [72194]=5, + [72195]=5, + [72196]=5, + [72197]=5, + [72198]=5, + [72201]=5, + [72202]=5, + [72243]=5, + [72244]=5, + [72245]=5, + [72246]=5, + [72247]=5, + [72248]=5, + [72251]=5, + [72252]=5, + [72253]=5, + [72254]=5, + [72263]=5, + [72273]=5, + [72274]=5, + [72275]=5, + [72276]=5, + [72277]=5, + [72278]=5, + [72281]=5, + [72282]=5, + [72283]=5, + [72330]=5, + [72331]=5, + [72332]=5, + [72333]=5, + [72334]=5, + [72335]=5, + [72336]=5, + [72337]=5, + [72338]=5, + [72339]=5, + [72340]=5, + [72341]=5, + [72342]=5, + [72344]=5, + [72345]=5, + [72752]=5, + [72753]=5, + [72754]=5, + [72755]=5, + [72756]=5, + [72757]=5, + [72758]=5, + [72760]=5, + [72761]=5, + [72762]=5, + [72763]=5, + [72764]=5, + [72765]=5, + [72767]=5, + [72850]=5, + [72851]=5, + [72852]=5, + [72853]=5, + [72854]=5, + [72855]=5, + [72856]=5, + [72857]=5, + [72858]=5, + [72859]=5, + [72860]=5, + [72861]=5, + [72862]=5, + [72863]=5, + [72864]=5, + [72865]=5, + [72866]=5, + [72867]=5, + [72868]=5, + [72869]=5, + [72870]=5, + [72871]=5, + [72874]=5, + [72875]=5, + [72876]=5, + [72877]=5, + [72878]=5, + [72879]=5, + [72880]=5, + [72882]=5, + [72883]=5, + [72885]=5, + [72886]=5, + [73009]=5, + [73010]=5, + [73011]=5, + [73012]=5, + [73013]=5, + [73014]=5, + [73018]=5, + [73020]=5, + [73021]=5, + [73023]=5, + [73024]=5, + [73025]=5, + [73026]=5, + [73027]=5, + [73028]=5, + [73029]=5, + [73031]=5, + [73104]=5, + [73105]=5, + [73109]=5, + [73111]=5, + [73459]=5, + [73460]=5, + [92912]=5, + [92913]=5, + [92914]=5, + [92915]=5, + [92916]=5, + [92976]=5, + [92977]=5, + [92978]=5, + [92979]=5, + [92980]=5, + [92981]=5, + [92982]=5, + [94031]=5, + [94095]=5, + [94096]=5, + [94097]=5, + [94098]=5, + [113821]=5, + [113822]=5, + [119143]=5, + [119144]=5, + [119145]=5, + [119163]=5, + [119164]=5, + [119165]=5, + [119166]=5, + [119167]=5, + [119168]=5, + [119169]=5, + [119170]=5, + [119173]=5, + [119174]=5, + [119175]=5, + [119176]=5, + [119177]=5, + [119178]=5, + [119179]=5, + [119210]=5, + [119211]=5, + [119212]=5, + [119213]=5, + [119362]=5, + [119363]=5, + [119364]=5, + [121344]=5, + [121345]=5, + [121346]=5, + [121347]=5, + [121348]=5, + [121349]=5, + [121350]=5, + [121351]=5, + [121352]=5, + [121353]=5, + [121354]=5, + [121355]=5, + [121356]=5, + [121357]=5, + [121358]=5, + [121359]=5, + [121360]=5, + [121361]=5, + [121362]=5, + [121363]=5, + [121364]=5, + [121365]=5, + [121366]=5, + [121367]=5, + [121368]=5, + [121369]=5, + [121370]=5, + [121371]=5, + [121372]=5, + [121373]=5, + [121374]=5, + [121375]=5, + [121376]=5, + [121377]=5, + [121378]=5, + [121379]=5, + [121380]=5, + [121381]=5, + [121382]=5, + [121383]=5, + [121384]=5, + [121385]=5, + [121386]=5, + [121387]=5, + [121388]=5, + [121389]=5, + [121390]=5, + [121391]=5, + [121392]=5, + [121393]=5, + [121394]=5, + [121395]=5, + [121396]=5, + [121397]=5, + [121398]=5, + [121403]=5, + [121404]=5, + [121405]=5, + [121406]=5, + [121407]=5, + [121408]=5, + [121409]=5, + [121410]=5, + [121411]=5, + [121412]=5, + [121413]=5, + [121414]=5, + [121415]=5, + [121416]=5, + [121417]=5, + [121418]=5, + [121419]=5, + [121420]=5, + [121421]=5, + [121422]=5, + [121423]=5, + [121424]=5, + [121425]=5, + [121426]=5, + [121427]=5, + [121428]=5, + [121429]=5, + [121430]=5, + [121431]=5, + [121432]=5, + [121433]=5, + [121434]=5, + [121435]=5, + [121436]=5, + [121437]=5, + [121438]=5, + [121439]=5, + [121440]=5, + [121441]=5, + [121442]=5, + [121443]=5, + [121444]=5, + [121445]=5, + [121446]=5, + [121447]=5, + [121448]=5, + [121449]=5, + [121450]=5, + [121451]=5, + [121452]=5, + [121461]=5, + [121476]=5, + [121499]=5, + [121500]=5, + [121501]=5, + [121502]=5, + [121503]=5, + [121505]=5, + [121506]=5, + [121507]=5, + [121508]=5, + [121509]=5, + [121510]=5, + [121511]=5, + [121512]=5, + [121513]=5, + [121514]=5, + [121515]=5, + [121516]=5, + [121517]=5, + [121518]=5, + [121519]=5, + [122880]=5, + [122881]=5, + [122882]=5, + [122883]=5, + [122884]=5, + [122885]=5, + [122886]=5, + [122888]=5, + [122889]=5, + [122890]=5, + [122891]=5, + [122892]=5, + [122893]=5, + [122894]=5, + [122895]=5, + [122896]=5, + [122897]=5, + [122898]=5, + [122899]=5, + [122900]=5, + [122901]=5, + [122902]=5, + [122903]=5, + [122904]=5, + [122907]=5, + [122908]=5, + [122909]=5, + [122910]=5, + [122911]=5, + [122912]=5, + [122913]=5, + [122915]=5, + [122916]=5, + [122918]=5, + [122919]=5, + [122920]=5, + [122921]=5, + [122922]=5, + [123184]=5, + [123185]=5, + [123186]=5, + [123187]=5, + [123188]=5, + [123189]=5, + [123190]=5, + [123628]=5, + [123629]=5, + [123630]=5, + [123631]=5, + [125136]=5, + [125137]=5, + [125138]=5, + [125139]=5, + [125140]=5, + [125141]=5, + [125142]=5, + [125184]=2, + [125185]=2, + [125186]=2, + [125187]=2, + [125188]=2, + [125189]=2, + [125190]=2, + [125191]=2, + [125192]=2, + [125193]=2, + [125194]=2, + [125195]=2, + [125196]=2, + [125197]=2, + [125198]=2, + [125199]=2, + [125200]=2, + [125201]=2, + [125202]=2, + [125203]=2, + [125204]=2, + [125205]=2, + [125206]=2, + [125207]=2, + [125208]=2, + [125209]=2, + [125210]=2, + [125211]=2, + [125212]=2, + [125213]=2, + [125214]=2, + [125215]=2, + [125216]=2, + [125217]=2, + [125218]=2, + [125219]=2, + [125220]=2, + [125221]=2, + [125222]=2, + [125223]=2, + [125224]=2, + [125225]=2, + [125226]=2, + [125227]=2, + [125228]=2, + [125229]=2, + [125230]=2, + [125231]=2, + [125232]=2, + [125233]=2, + [125234]=2, + [125235]=2, + [125236]=2, + [125237]=2, + [125238]=2, + [125239]=2, + [125240]=2, + [125241]=2, + [125242]=2, + [125243]=2, + [125244]=2, + [125245]=2, + [125246]=2, + [125247]=2, + [125248]=2, + [125249]=2, + [125250]=2, + [125251]=2, + [125252]=5, + [125253]=5, + [125254]=5, + [125255]=5, + [125256]=5, + [125257]=5, + [125258]=5, + [1042752]=5, +} +characters.indicgroups={ + ["above_mark"]={ + [2304]=true, + [2305]=true, + [2306]=true, + [2362]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2385]=true, + [2387]=true, + [2388]=true, + [2389]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2690]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2879]=true, + [3008]=true, + [3021]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3142]=true, + [3143]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3149]=true, + [3263]=true, + [3270]=true, + [3406]=true, + [4141]=true, + [4142]=true, + [4146]=true, + [4147]=true, + [4148]=true, + [4149]=true, + [4150]=true, + [4154]=true, + [4209]=true, + [4210]=true, + [4211]=true, + [4212]=true, + [4229]=true, + [4230]=true, + [4253]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43248]=true, + [43249]=true, + [43493]=true, + [43644]=true, + }, + ["after_half"]={}, + ["after_main"]={ + [2864]=true, + [2879]=true, + [2902]=true, + [3376]=true, + }, + ["after_postscript"]={ + [2433]=true, + [2494]=true, + [2496]=true, + [2519]=true, + [2561]=true, + [2562]=true, + [2622]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2672]=true, + [2673]=true, + [2735]=true, + [2750]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2786]=true, + [2787]=true, + [2878]=true, + [2880]=true, + [2903]=true, + [2992]=true, + [3006]=true, + [3007]=true, + [3009]=true, + [3010]=true, + [3031]=true, + [3120]=true, + [3248]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3415]=true, + }, + ["after_subscript"]={ + [2366]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2402]=true, + [2403]=true, + [2480]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2530]=true, + [2531]=true, + [2544]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [3008]=true, + [3139]=true, + [3140]=true, + [3267]=true, + [3268]=true, + [3285]=true, + [3286]=true, + }, + ["anudatta"]={ + [2386]=true, + }, + ["before_half"]={ + [2367]=true, + [2382]=true, + [2495]=true, + [2503]=true, + [2504]=true, + [2623]=true, + [2751]=true, + [2887]=true, + }, + ["before_main"]={ + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, + }, + ["before_postscript"]={ + [2352]=true, + [2736]=true, + }, + ["before_subscript"]={ + [2608]=true, + [2817]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3142]=true, + [3143]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3157]=true, + [3158]=true, + [3262]=true, + [3263]=true, + [3265]=true, + [3266]=true, + [3270]=true, + [3276]=true, + [3298]=true, + [3299]=true, + }, + ["below_mark"]={ + [2364]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2381]=true, + [2386]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2492]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2509]=true, + [2620]=true, + [2625]=true, + [2626]=true, + [2637]=true, + [2748]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2765]=true, + [2876]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2893]=true, + [2914]=true, + [2915]=true, + [3009]=true, + [3010]=true, + [3170]=true, + [3171]=true, + [3260]=true, + [3286]=true, + [3298]=true, + [3299]=true, + [3426]=true, + [3427]=true, + [4143]=true, + [4144]=true, + [4151]=true, + [4153]=true, + [4157]=true, + [4158]=true, + [4184]=true, + [4185]=true, + [4190]=true, + [4191]=true, + [4192]=true, + [4226]=true, + [4237]=true, + }, + ["consonant"]={ + [2325]=true, + [2326]=true, + [2327]=true, + [2328]=true, + [2329]=true, + [2330]=true, + [2331]=true, + [2332]=true, + [2333]=true, + [2334]=true, + [2335]=true, + [2336]=true, + [2337]=true, + [2338]=true, + [2339]=true, + [2340]=true, + [2341]=true, + [2342]=true, + [2343]=true, + [2344]=true, + [2345]=true, + [2346]=true, + [2347]=true, + [2348]=true, + [2349]=true, + [2350]=true, + [2351]=true, + [2352]=true, + [2353]=true, + [2354]=true, + [2355]=true, + [2356]=true, + [2357]=true, + [2358]=true, + [2359]=true, + [2360]=true, + [2361]=true, + [2392]=true, + [2393]=true, + [2394]=true, + [2395]=true, + [2396]=true, + [2397]=true, + [2398]=true, + [2399]=true, + [2424]=true, + [2425]=true, + [2426]=true, + [2453]=true, + [2454]=true, + [2455]=true, + [2456]=true, + [2457]=true, + [2458]=true, + [2459]=true, + [2460]=true, + [2461]=true, + [2462]=true, + [2463]=true, + [2464]=true, + [2465]=true, + [2466]=true, + [2467]=true, + [2468]=true, + [2469]=true, + [2470]=true, + [2471]=true, + [2472]=true, + [2474]=true, + [2475]=true, + [2476]=true, + [2477]=true, + [2478]=true, + [2479]=true, + [2480]=true, + [2482]=true, + [2486]=true, + [2487]=true, + [2488]=true, + [2489]=true, + [2510]=true, + [2524]=true, + [2525]=true, + [2527]=true, + [2581]=true, + [2582]=true, + [2583]=true, + [2584]=true, + [2585]=true, + [2586]=true, + [2587]=true, + [2588]=true, + [2589]=true, + [2590]=true, + [2591]=true, + [2592]=true, + [2593]=true, + [2594]=true, + [2595]=true, + [2596]=true, + [2597]=true, + [2598]=true, + [2599]=true, + [2600]=true, + [2602]=true, + [2603]=true, + [2604]=true, + [2605]=true, + [2606]=true, + [2607]=true, + [2608]=true, + [2610]=true, + [2611]=true, + [2613]=true, + [2614]=true, + [2616]=true, + [2617]=true, + [2649]=true, + [2650]=true, + [2651]=true, + [2652]=true, + [2654]=true, + [2709]=true, + [2710]=true, + [2711]=true, + [2712]=true, + [2713]=true, + [2714]=true, + [2715]=true, + [2716]=true, + [2717]=true, + [2718]=true, + [2719]=true, + [2720]=true, + [2721]=true, + [2722]=true, + [2723]=true, + [2724]=true, + [2725]=true, + [2726]=true, + [2727]=true, + [2728]=true, + [2730]=true, + [2731]=true, + [2732]=true, + [2733]=true, + [2734]=true, + [2735]=true, + [2736]=true, + [2738]=true, + [2739]=true, + [2741]=true, + [2742]=true, + [2743]=true, + [2744]=true, + [2745]=true, + [2837]=true, + [2838]=true, + [2839]=true, + [2840]=true, + [2841]=true, + [2842]=true, + [2843]=true, + [2844]=true, + [2845]=true, + [2846]=true, + [2847]=true, + [2848]=true, + [2849]=true, + [2850]=true, + [2851]=true, + [2852]=true, + [2853]=true, + [2854]=true, + [2855]=true, + [2856]=true, + [2858]=true, + [2859]=true, + [2860]=true, + [2861]=true, + [2862]=true, + [2863]=true, + [2864]=true, + [2866]=true, + [2867]=true, + [2869]=true, + [2870]=true, + [2871]=true, + [2872]=true, + [2873]=true, + [2908]=true, + [2909]=true, + [2929]=true, + [2965]=true, + [2969]=true, + [2970]=true, + [2972]=true, + [2974]=true, + [2975]=true, + [2979]=true, + [2980]=true, + [2984]=true, + [2985]=true, + [2986]=true, + [2990]=true, + [2991]=true, + [2992]=true, + [2993]=true, + [2994]=true, + [2995]=true, + [2996]=true, + [2997]=true, + [2998]=true, + [2999]=true, + [3000]=true, + [3001]=true, + [3093]=true, + [3094]=true, + [3095]=true, + [3096]=true, + [3097]=true, + [3098]=true, + [3099]=true, + [3100]=true, + [3101]=true, + [3102]=true, + [3103]=true, + [3104]=true, + [3105]=true, + [3106]=true, + [3107]=true, + [3108]=true, + [3109]=true, + [3110]=true, + [3111]=true, + [3112]=true, + [3114]=true, + [3115]=true, + [3116]=true, + [3117]=true, + [3118]=true, + [3119]=true, + [3120]=true, + [3121]=true, + [3122]=true, + [3123]=true, + [3124]=true, + [3125]=true, + [3126]=true, + [3127]=true, + [3128]=true, + [3129]=true, + [3133]=true, + [3221]=true, + [3222]=true, + [3223]=true, + [3224]=true, + [3225]=true, + [3226]=true, + [3227]=true, + [3228]=true, + [3229]=true, + [3230]=true, + [3231]=true, + [3232]=true, + [3233]=true, + [3234]=true, + [3235]=true, + [3236]=true, + [3237]=true, + [3238]=true, + [3239]=true, + [3240]=true, + [3242]=true, + [3243]=true, + [3244]=true, + [3245]=true, + [3246]=true, + [3247]=true, + [3248]=true, + [3249]=true, + [3250]=true, + [3251]=true, + [3253]=true, + [3254]=true, + [3255]=true, + [3256]=true, + [3257]=true, + [3294]=true, + [3349]=true, + [3350]=true, + [3351]=true, + [3352]=true, + [3353]=true, + [3354]=true, + [3355]=true, + [3356]=true, + [3357]=true, + [3358]=true, + [3359]=true, + [3360]=true, + [3361]=true, + [3362]=true, + [3363]=true, + [3364]=true, + [3365]=true, + [3366]=true, + [3367]=true, + [3368]=true, + [3369]=true, + [3370]=true, + [3371]=true, + [3372]=true, + [3373]=true, + [3374]=true, + [3375]=true, + [3376]=true, + [3377]=true, + [3378]=true, + [3379]=true, + [3380]=true, + [3381]=true, + [3382]=true, + [3383]=true, + [3384]=true, + [3385]=true, + [3386]=true, + [4096]=true, + [4097]=true, + [4098]=true, + [4099]=true, + [4100]=true, + [4101]=true, + [4102]=true, + [4103]=true, + [4104]=true, + [4105]=true, + [4106]=true, + [4107]=true, + [4108]=true, + [4109]=true, + [4110]=true, + [4111]=true, + [4112]=true, + [4113]=true, + [4114]=true, + [4115]=true, + [4116]=true, + [4117]=true, + [4118]=true, + [4119]=true, + [4120]=true, + [4121]=true, + [4122]=true, + [4123]=true, + [4124]=true, + [4125]=true, + [4126]=true, + [4127]=true, + [4128]=true, + [4155]=true, + [4156]=true, + [4157]=true, + [4158]=true, + [4159]=true, + [4176]=true, + [4177]=true, + [4186]=true, + [4187]=true, + [4188]=true, + [4189]=true, + [4190]=true, + [4191]=true, + [4192]=true, + [4193]=true, + [4197]=true, + [4198]=true, + [4206]=true, + [4207]=true, + [4208]=true, + [4213]=true, + [4214]=true, + [4215]=true, + [4216]=true, + [4217]=true, + [4218]=true, + [4219]=true, + [4220]=true, + [4221]=true, + [4222]=true, + [4223]=true, + [4224]=true, + [4225]=true, + [4226]=true, + [4238]=true, + [43488]=true, + [43489]=true, + [43490]=true, + [43491]=true, + [43492]=true, + [43495]=true, + [43496]=true, + [43497]=true, + [43498]=true, + [43499]=true, + [43500]=true, + [43501]=true, + [43502]=true, + [43503]=true, + [43514]=true, + [43515]=true, + [43516]=true, + [43517]=true, + [43518]=true, + [43616]=true, + [43617]=true, + [43618]=true, + [43619]=true, + [43620]=true, + [43621]=true, + [43622]=true, + [43623]=true, + [43624]=true, + [43625]=true, + [43626]=true, + [43628]=true, + [43629]=true, + [43630]=true, + [43631]=true, + [43633]=true, + [43634]=true, + [43635]=true, + [43636]=true, + [43637]=true, + [43638]=true, + [43642]=true, + [43646]=true, + [43647]=true, + }, + ["dependent_vowel"]={ + [2362]=true, + [2363]=true, + [2366]=true, + [2367]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2382]=true, + [2383]=true, + [2389]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2494]=true, + [2495]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2503]=true, + [2504]=true, + [2507]=true, + [2508]=true, + [2622]=true, + [2623]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2750]=true, + [2751]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2879]=true, + [2880]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2887]=true, + [2888]=true, + [2891]=true, + [2892]=true, + [2914]=true, + [2915]=true, + [3006]=true, + [3007]=true, + [3008]=true, + [3009]=true, + [3010]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3018]=true, + [3019]=true, + [3020]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3142]=true, + [3143]=true, + [3144]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3170]=true, + [3171]=true, + [3262]=true, + [3263]=true, + [3264]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3270]=true, + [3271]=true, + [3272]=true, + [3274]=true, + [3275]=true, + [3276]=true, + [3285]=true, + [3286]=true, + [3298]=true, + [3299]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3398]=true, + [3399]=true, + [3400]=true, + [3402]=true, + [3403]=true, + [3404]=true, + [3415]=true, + [3426]=true, + [3427]=true, + [4139]=true, + [4140]=true, + [4141]=true, + [4142]=true, + [4143]=true, + [4144]=true, + [4145]=true, + [4146]=true, + [4147]=true, + [4148]=true, + [4149]=true, + [4182]=true, + [4183]=true, + [4184]=true, + [4185]=true, + [4194]=true, + [4199]=true, + [4200]=true, + [4209]=true, + [4210]=true, + [4211]=true, + [4212]=true, + [4227]=true, + [4228]=true, + [4229]=true, + [4230]=true, + [4252]=true, + [4253]=true, + [43493]=true, + }, + ["halant"]={ + [2381]=true, + [2509]=true, + [2637]=true, + [2765]=true, + [2893]=true, + [3021]=true, + [3149]=true, + [3277]=true, + [3405]=true, + }, + ["independent_vowel"]={ + [2308]=true, + [2309]=true, + [2310]=true, + [2311]=true, + [2312]=true, + [2313]=true, + [2314]=true, + [2315]=true, + [2316]=true, + [2317]=true, + [2318]=true, + [2319]=true, + [2320]=true, + [2321]=true, + [2322]=true, + [2323]=true, + [2324]=true, + [2400]=true, + [2401]=true, + [2418]=true, + [2419]=true, + [2420]=true, + [2421]=true, + [2422]=true, + [2423]=true, + [2437]=true, + [2438]=true, + [2439]=true, + [2440]=true, + [2441]=true, + [2442]=true, + [2443]=true, + [2444]=true, + [2447]=true, + [2448]=true, + [2451]=true, + [2452]=true, + [2528]=true, + [2529]=true, + [2530]=true, + [2531]=true, + [2565]=true, + [2566]=true, + [2567]=true, + [2568]=true, + [2569]=true, + [2570]=true, + [2575]=true, + [2576]=true, + [2579]=true, + [2580]=true, + [2693]=true, + [2694]=true, + [2695]=true, + [2696]=true, + [2697]=true, + [2698]=true, + [2699]=true, + [2700]=true, + [2701]=true, + [2703]=true, + [2704]=true, + [2705]=true, + [2707]=true, + [2708]=true, + [2784]=true, + [2785]=true, + [2786]=true, + [2787]=true, + [2821]=true, + [2822]=true, + [2823]=true, + [2824]=true, + [2825]=true, + [2826]=true, + [2827]=true, + [2828]=true, + [2831]=true, + [2832]=true, + [2835]=true, + [2836]=true, + [2912]=true, + [2913]=true, + [2949]=true, + [2950]=true, + [2951]=true, + [2952]=true, + [2953]=true, + [2954]=true, + [2958]=true, + [2959]=true, + [2960]=true, + [2962]=true, + [2963]=true, + [2964]=true, + [3077]=true, + [3078]=true, + [3079]=true, + [3080]=true, + [3081]=true, + [3082]=true, + [3083]=true, + [3084]=true, + [3086]=true, + [3087]=true, + [3088]=true, + [3090]=true, + [3091]=true, + [3092]=true, + [3168]=true, + [3169]=true, + [3205]=true, + [3206]=true, + [3207]=true, + [3208]=true, + [3209]=true, + [3210]=true, + [3211]=true, + [3212]=true, + [3214]=true, + [3215]=true, + [3216]=true, + [3218]=true, + [3219]=true, + [3220]=true, + [3296]=true, + [3297]=true, + [3333]=true, + [3334]=true, + [3335]=true, + [3336]=true, + [3337]=true, + [3338]=true, + [3339]=true, + [3340]=true, + [3342]=true, + [3343]=true, + [3344]=true, + [3346]=true, + [3347]=true, + [3348]=true, + [3423]=true, + [3424]=true, + [3425]=true, + [4129]=true, + [4130]=true, + [4131]=true, + [4132]=true, + [4133]=true, + [4134]=true, + [4135]=true, + [4136]=true, + [4137]=true, + [4138]=true, + [4178]=true, + [4179]=true, + [4180]=true, + [4181]=true, + }, + ["nukta"]={ + [2364]=true, + [2492]=true, + [2620]=true, + [2748]=true, + [2876]=true, + [3260]=true, + }, + ["post_mark"]={ + [2307]=true, + [2363]=true, + [2366]=true, + [2368]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2383]=true, + [2494]=true, + [2496]=true, + [2622]=true, + [2624]=true, + [2750]=true, + [2752]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2880]=true, + [3006]=true, + [3007]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3262]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3276]=true, + [3285]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3415]=true, + [4139]=true, + [4140]=true, + [4152]=true, + [4155]=true, + [4182]=true, + [4183]=true, + [4194]=true, + [4195]=true, + [4196]=true, + [4199]=true, + [4200]=true, + [4201]=true, + [4202]=true, + [4203]=true, + [4204]=true, + [4205]=true, + [4227]=true, + [4231]=true, + [4232]=true, + [4233]=true, + [4234]=true, + [4235]=true, + [4236]=true, + [4239]=true, + [4250]=true, + [4251]=true, + [4252]=true, + [43643]=true, + [43645]=true, + }, + ["pre_mark"]={ + [2367]=true, + [2382]=true, + [2495]=true, + [2503]=true, + [2504]=true, + [2623]=true, + [2751]=true, + [2887]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, + [4145]=true, + [4228]=true, + }, + ["ra"]={ + [2352]=true, + [2480]=true, + [2544]=true, + [2608]=true, + [2736]=true, + [2864]=true, + [2992]=true, + [3120]=true, + [3248]=true, + [3376]=true, + }, + ["stress_tone_mark"]={ + [2385]=true, + [2386]=true, + [2387]=true, + [2388]=true, + [4151]=true, + [4195]=true, + [4196]=true, + [4201]=true, + [4202]=true, + [4203]=true, + [4204]=true, + [4205]=true, + [4231]=true, + [4232]=true, + [4233]=true, + [4234]=true, + [4235]=true, + [4236]=true, + [4237]=true, + [4239]=true, + [4250]=true, + [4251]=true, + [43643]=true, + [43644]=true, + [43645]=true, + }, + ["twopart_mark"]={ + [2507]={ 2503,2494 }, + [2508]={ 2503,2519 }, + [2888]={ 2887,2902 }, + [2891]={ 2887,2878 }, + [2892]={ 2887,2903 }, + [3018]={ 3014,3006 }, + [3019]={ 3015,3006 }, + [3020]={ 3014,3031 }, + [3144]={ 3142,3158 }, + [3264]={ 3263,3285 }, + [3271]={ 3270,3285 }, + [3272]={ 3270,3286 }, + [3274]={ 3270,3266 }, + [3275]={ 3274,3285 }, + [3402]={ 3398,3390 }, + [3403]={ 3399,3390 }, + [3404]={ 3398,3415 }, + }, + ["vowel_modifier"]={ + [2304]=true, + [2305]=true, + [2306]=true, + [2307]=true, + [2433]=true, + [3330]=true, + [3331]=true, + [4150]=true, + [4152]=true, + [4153]=true, + [4154]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43249]=true, + }, +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] --- + +if not modules then modules={} end modules ['font-ini']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local allocate=utilities.storage.allocate +local sortedhash=table.sortedhash +fonts=fonts or {} +local fonts=fonts +local identifiers=allocate() +fonts.hashes=fonts.hashes or { identifiers=identifiers } +fonts.tables=fonts.tables or {} +fonts.helpers=fonts.helpers or {} +fonts.tracers=fonts.tracers or {} +fonts.specifiers=fonts.specifiers or {} +fonts.analyzers={} +fonts.readers={} +fonts.definers={ methods={} } +fonts.loggers={ register=function() end } +if context then + font.originaleach=font.each + function font.each() + return sortedhash(identifiers) + end + fontloader=nil +end +fonts.privateoffsets={ + textbase=0xF0000, + textextrabase=0xFD000, + mathextrabase=0xFE000, + mathbase=0xFF000, + keepnames=false, +} +if node and not tex.getfontoffamily then + tex.getfontoffamily=node.family_font +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] --- + +if not modules then modules={} end modules ['luatex-font-mis']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local currentfont=font.current +local hashes=fonts.hashes +local identifiers=hashes.identifiers or {} +local marks=hashes.marks or {} +hashes.identifiers=identifiers +hashes.marks=marks +table.setmetatableindex(marks,function(t,k) + if k==true then + return marks[currentfont()] + else + local resources=identifiers[k].resources or {} + local marks=resources.marks or {} + t[k]=marks + return marks + end +end) +function font.each() + return table.sortedhash(fonts.hashes.identifiers) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con” a3eb543fa5946fa1faf0e1e50d5b3b91] --- + +if not modules then modules={} end modules ['font-con']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget +local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find +local sort,insert,concat=table.sort,table.insert,table.concat +local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy +local derivetable=table.derive +local ioflush=io.flush +local round=math.round +local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) +local report_defining=logs.reporter("fonts","defining") +local fonts=fonts +local constructors=fonts.constructors or {} +fonts.constructors=constructors +local handlers=fonts.handlers or {} +fonts.handlers=handlers +local allocate=utilities.storage.allocate +local setmetatableindex=table.setmetatableindex +constructors.dontembed=allocate() +constructors.namemode="fullpath" +constructors.version=1.01 +constructors.cache=containers.define("fonts","constructors",constructors.version,false) +constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 +constructors.cacheintex=true +constructors.addtounicode=true +constructors.fixprotrusion=true +local designsizes=allocate() +constructors.designsizes=designsizes +local loadedfonts=allocate() +constructors.loadedfonts=loadedfonts +local factors={ + pt=65536.0, + bp=65781.8, +} +function constructors.setfactor(f) + constructors.factor=factors[f or 'pt'] or factors.pt +end +constructors.setfactor() +function constructors.scaled(scaledpoints,designsize) + if scaledpoints<0 then + local factor=constructors.factor + if designsize then + if designsize>factor then + return (- scaledpoints/1000)*designsize + else + return (- scaledpoints/1000)*designsize*factor + end + else + return (- scaledpoints/1000)*10*factor + end + else + return scaledpoints + end +end +function constructors.getprivate(tfmdata) + local properties=tfmdata.properties + local private=properties.private + properties.private=private+1 + return private +end +function constructors.setmathparameter(tfmdata,name,value) + local m=tfmdata.mathparameters + local c=tfmdata.MathConstants + if m then + m[name]=value + end + if c and c~=m then + c[name]=value + end +end +function constructors.getmathparameter(tfmdata,name) + local p=tfmdata.mathparameters or tfmdata.MathConstants + if p then + return p[name] + end +end +function constructors.cleanuptable(tfmdata) +end +function constructors.calculatescale(tfmdata,scaledpoints) + local parameters=tfmdata.parameters + if scaledpoints<0 then + scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) + end + return scaledpoints,scaledpoints/(parameters.units or 1000) +end +local unscaled={ + ScriptPercentScaleDown=true, + ScriptScriptPercentScaleDown=true, + RadicalDegreeBottomRaisePercent=true, + NoLimitSupFactor=true, + NoLimitSubFactor=true, +} +function constructors.assignmathparameters(target,original) + local mathparameters=original.mathparameters + if mathparameters and next(mathparameters) then + local targetparameters=target.parameters + local targetproperties=target.properties + local targetmathparameters={} + local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor + for name,value in next,mathparameters do + if unscaled[name] then + targetmathparameters[name]=value + else + targetmathparameters[name]=value*factor + end + end + if not targetmathparameters.FractionDelimiterSize then + targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size + end + if not mathparameters.FractionDelimiterDisplayStyleSize then + targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size + end + if not targetmathparameters.SpaceBeforeScript then + targetmathparameters.SpaceBeforeScript=targetmathparameters.SpaceAfterScript + end + target.mathparameters=targetmathparameters + end +end +function constructors.beforecopyingcharacters(target,original) +end +function constructors.aftercopyingcharacters(target,original) +end +local nofinstances=0 +local instances=setmetatableindex(function(t,k) + nofinstances=nofinstances+1 + t[k]=nofinstances + return nofinstances +end) +function constructors.trytosharefont(target,tfmdata) + local properties=target.properties + local instance=properties.instance + if instance then + local fullname=target.fullname + local fontname=target.fontname + local psname=target.psname + local format=tfmdata.properties.format + if format=="opentype" then + target.streamprovider=1 + elseif format=="truetype" then + target.streamprovider=2 + else + target.streamprovider=0 + end + if target.streamprovider>0 then + if fullname then + fullname=fullname..":"..instances[instance] + target.fullname=fullname + end + if fontname then + fontname=fontname..":"..instances[instance] + target.fontname=fontname + end + if psname then + psname=psname..":"..instances[instance] + target.psname=psname + end + end + end +end +local synonyms={ + exheight="x_height", + xheight="x_height", + ex="x_height", + emwidth="quad", + em="quad", + spacestretch="space_stretch", + stretch="space_stretch", + spaceshrink="space_shrink", + shrink="space_shrink", + extraspace="extra_space", + xspace="extra_space", + slantperpoint="slant", +} +function constructors.enhanceparameters(parameters) + local mt=getmetatable(parameters) + local getter=function(t,k) + if not k then + return nil + end + local s=synonyms[k] + if s then + return rawget(t,s) or (mt and mt[s]) or nil + end + if k=="spacing" then + return { + width=t.space, + stretch=t.space_stretch, + shrink=t.space_shrink, + extra=t.extra_space, + } + end + return mt and mt[k] or nil + end + local setter=function(t,k,v) + if not k then + return 0 + end + local s=synonyms[k] + if s then + rawset(t,s,v) + elseif k=="spacing" then + if type(v)=="table" then + rawset(t,"space",v.width or 0) + rawset(t,"space_stretch",v.stretch or 0) + rawset(t,"space_shrink",v.shrink or 0) + rawset(t,"extra_space",v.extra or 0) + end + else + rawset(t,k,v) + end + end + setmetatable(parameters,{ + __index=getter, + __newindex=setter, + }) +end +local function mathkerns(v,vdelta) + local k={} + for i=1,#v do + local entry=v[i] + local height=entry.height + local kern=entry.kern + k[i]={ + height=height and vdelta*height or 0, + kern=kern and vdelta*kern or 0, + } + end + return k +end +local psfake=0 +local function fixedpsname(psname,fallback) + local usedname=psname + if psname and psname~="" then + if find(psname," ",1,true) then + usedname=gsub(psname,"[%s]+","-") + else + end + elseif not fallback or fallback=="" then + psfake=psfake+1 + psname="fakename-"..psfake + else + psname=fallback + usedname=gsub(psname,"[^a-zA-Z0-9]+","-") + end + return usedname,psname~=usedname +end +function constructors.scale(tfmdata,specification) + local target={} + if tonumber(specification) then + specification={ size=specification } + end + target.specification=specification + local scaledpoints=specification.size + local relativeid=specification.relativeid + local properties=tfmdata.properties or {} + local goodies=tfmdata.goodies or {} + local resources=tfmdata.resources or {} + local descriptions=tfmdata.descriptions or {} + local characters=tfmdata.characters or {} + local changed=tfmdata.changed or {} + local shared=tfmdata.shared or {} + local parameters=tfmdata.parameters or {} + local mathparameters=tfmdata.mathparameters or {} + local targetcharacters={} + local targetdescriptions=derivetable(descriptions) + local targetparameters=derivetable(parameters) + local targetproperties=derivetable(properties) + local targetgoodies=goodies + target.characters=targetcharacters + target.descriptions=targetdescriptions + target.parameters=targetparameters + target.properties=targetproperties + target.goodies=targetgoodies + target.shared=shared + target.resources=resources + target.unscaled=tfmdata + local mathsize=tonumber(specification.mathsize) or 0 + local textsize=tonumber(specification.textsize) or scaledpoints + local forcedsize=tonumber(parameters.mathsize ) or 0 + local extrafactor=tonumber(specification.factor ) or 1 + if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then + scaledpoints=parameters.scriptpercentage*textsize/100 + elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then + scaledpoints=parameters.scriptscriptpercentage*textsize/100 + elseif forcedsize>1000 then + scaledpoints=forcedsize + else + end + targetparameters.mathsize=mathsize + targetparameters.textsize=textsize + targetparameters.forcedsize=forcedsize + targetparameters.extrafactor=extrafactor + local addtounicode=constructors.addtounicode + local tounicode=fonts.mappings.tounicode + local unknowncode=tounicode(0xFFFD) + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local units=parameters.units or 1000 + targetproperties.language=properties.language or "dflt" + targetproperties.script=properties.script or "dflt" + targetproperties.mode=properties.mode or "base" + targetproperties.method=properties.method + local askedscaledpoints=scaledpoints + local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) + local hdelta=delta + local vdelta=delta + target.designsize=parameters.designsize + target.units=units + target.units_per_em=units + local direction=properties.direction or tfmdata.direction or 0 + target.direction=direction + properties.direction=direction + target.size=scaledpoints + target.encodingbytes=properties.encodingbytes or 1 + target.subfont=properties.subfont + target.embedding=properties.embedding or "subset" + target.tounicode=1 + target.cidinfo=properties.cidinfo + target.format=properties.format + target.cache=constructors.cacheintex and "yes" or "renew" + local original=properties.original or tfmdata.original + local fontname=properties.fontname or tfmdata.fontname + local fullname=properties.fullname or tfmdata.fullname + local filename=properties.filename or tfmdata.filename + local psname=properties.psname or tfmdata.psname + local name=properties.name or tfmdata.name + local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) + target.original=original + target.fontname=fontname + target.fullname=fullname + target.filename=filename + target.psname=psname + target.name=name + properties.fontname=fontname + properties.fullname=fullname + properties.filename=filename + properties.psname=psname + properties.name=name + local expansion=parameters.expansion + if expansion then + target.stretch=expansion.stretch + target.shrink=expansion.shrink + target.step=expansion.step + end + local slantfactor=parameters.slantfactor or 0 + if slantfactor~=0 then + target.slant=slantfactor*1000 + else + target.slant=0 + end + local extendfactor=parameters.extendfactor or 0 + if extendfactor~=0 and extendfactor~=1 then + hdelta=hdelta*extendfactor + target.extend=extendfactor*1000 + else + target.extend=1000 + end + local squeezefactor=parameters.squeezefactor or 0 + if squeezefactor~=0 and squeezefactor~=1 then + vdelta=vdelta*squeezefactor + target.squeeze=squeezefactor*1000 + else + target.squeeze=1000 + end + local mode=parameters.mode or 0 + if mode~=0 then + target.mode=mode + end + local width=parameters.width or 0 + if width~=0 then + target.width=width*delta*1000/655360 + end + targetparameters.factor=delta + targetparameters.hfactor=hdelta + targetparameters.vfactor=vdelta + targetparameters.size=scaledpoints + targetparameters.units=units + targetparameters.scaledpoints=askedscaledpoints + targetparameters.mode=mode + targetparameters.width=width + local isvirtual=properties.virtualized or tfmdata.type=="virtual" + local hasquality=parameters.expansion or parameters.protrusion + local hasitalics=properties.hasitalics + local autoitalicamount=properties.autoitalicamount + local stackmath=not properties.nostackmath + local haskerns=properties.haskerns or properties.mode=="base" + local hasligatures=properties.hasligatures or properties.mode=="base" + local realdimensions=properties.realdimensions + local writingmode=properties.writingmode or "horizontal" + local identity=properties.identity or "horizontal" + local vfonts=target.fonts + if vfonts and #vfonts>0 then + target.fonts=fastcopy(vfonts) + elseif isvirtual then + target.fonts={ { id=0 } } + end + if changed and not next(changed) then + changed=false + end + target.type=isvirtual and "virtual" or "real" + target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" + target.identity=identity=="vertical" and "vertical" or "horizontal" + target.postprocessors=tfmdata.postprocessors + local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt + local targetspace=(parameters.space or parameters[2] or 0)*hdelta + local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta + local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta + local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta + local targetquad=(parameters.quad or parameters[6] or 0)*hdelta + local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta + targetparameters.slant=targetslant + targetparameters.space=targetspace + targetparameters.space_stretch=targetspace_stretch + targetparameters.space_shrink=targetspace_shrink + targetparameters.x_height=targetx_height + targetparameters.quad=targetquad + targetparameters.extra_space=targetextra_space + local hshift=parameters.hshift + if hshift then + targetparameters.hshift=delta*hshift + end + local vshift=parameters.vshift + if vshift then + targetparameters.vshift=delta*vshift + end + local ascender=parameters.ascender + if ascender then + targetparameters.ascender=delta*ascender + end + local descender=parameters.descender + if descender then + targetparameters.descender=delta*descender + end + constructors.enhanceparameters(targetparameters) + local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 + local scaledwidth=defaultwidth*hdelta + local scaledheight=defaultheight*vdelta + local scaleddepth=defaultdepth*vdelta + local hasmath=(properties.hasmath or next(mathparameters)) and true + if hasmath then + constructors.assignmathparameters(target,tfmdata) + properties.hasmath=true + target.nomath=false + target.MathConstants=target.mathparameters + else + properties.hasmath=false + target.nomath=true + target.mathparameters=nil + end + if hasmath then + local mathitalics=properties.mathitalics + if mathitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + else + local textitalics=properties.textitalics + if textitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + end + if trace_defining then + report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", + name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, + hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") + end + constructors.beforecopyingcharacters(target,tfmdata) + local sharedkerns={} + for unicode,character in next,characters do + local chr,description,index + if changed then + local c=changed[unicode] + if c and c~=unicode then + if c then + description=descriptions[c] or descriptions[unicode] or character + character=characters[c] or character + index=description.index or c + else + description=descriptions[unicode] or character + index=description.index or unicode + end + else + description=descriptions[unicode] or character + index=description.index or unicode + end + else + description=descriptions[unicode] or character + index=description.index or unicode + end + local width=description.width + local height=description.height + local depth=description.depth + local isunicode=description.unicode + if realdimensions then + if not height or height==0 then + local bb=description.boundingbox + local ht=bb[4] + if ht~=0 then + height=ht + end + if not depth or depth==0 then + local dp=-bb[2] + if dp~=0 then + depth=dp + end + end + elseif not depth or depth==0 then + local dp=-description.boundingbox[2] + if dp~=0 then + depth=dp + end + end + end + if width then width=hdelta*width else width=scaledwidth end + if height then height=vdelta*height else height=scaledheight end + if depth and depth~=0 then + depth=delta*depth + if isunicode then + chr={ + index=index, + height=height, + depth=depth, + width=width, + unicode=isunicode, + } + else + chr={ + index=index, + height=height, + depth=depth, + width=width, + } + end + else + if isunicode then + chr={ + index=index, + height=height, + width=width, + unicode=isunicode, + } + else + chr={ + index=index, + height=height, + width=width, + } + end + end + if addtounicode then + chr.tounicode=isunicode and tounicode(isunicode) or unknowncode + end + if hasquality then + local ve=character.expansion_factor + if ve then + chr.expansion_factor=ve*1000 + end + local vl=character.left_protruding + if vl then + chr.left_protruding=protrusionfactor*width*vl + end + local vr=character.right_protruding + if vr then + chr.right_protruding=protrusionfactor*width*vr + end + end + if hasmath then + local vn=character.next + if vn then + chr.next=vn + else + local vv=character.vert_variants + if vv then + local t={} + for i=1,#vv do + local vvi=vv[i] + local s=vvi["start"] or 0 + local e=vvi["end"] or 0 + local a=vvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*vdelta, + ["end"]=e==0 and 0 or e*vdelta, + ["advance"]=a==0 and 0 or a*vdelta, + ["extender"]=vvi["extender"], + ["glyph"]=vvi["glyph"], + } + end + chr.vert_variants=t + else + local hv=character.horiz_variants + if hv then + local t={} + for i=1,#hv do + local hvi=hv[i] + local s=hvi["start"] or 0 + local e=hvi["end"] or 0 + local a=hvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*hdelta, + ["end"]=e==0 and 0 or e*hdelta, + ["advance"]=a==0 and 0 or a*hdelta, + ["extender"]=hvi["extender"], + ["glyph"]=hvi["glyph"], + } + end + chr.horiz_variants=t + end + end + end + local vi=character.vert_italic + if vi and vi~=0 then + chr.vert_italic=vi*hdelta + end + local va=character.accent + if va then + chr.top_accent=vdelta*va + end + if stackmath then + local mk=character.mathkerns + if mk then + local tr=mk.topright + local tl=mk.topleft + local br=mk.bottomright + local bl=mk.bottomleft + chr.mathkern={ + top_right=tr and mathkerns(tr,vdelta) or nil, + top_left=tl and mathkerns(tl,vdelta) or nil, + bottom_right=br and mathkerns(br,vdelta) or nil, + bottom_left=bl and mathkerns(bl,vdelta) or nil, + } + end + end + if hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + elseif autoitalicamount then + local vi=description.italic + if not vi then + local bb=description.boundingbox + if bb then + local vi=bb[3]-description.width+autoitalicamount + if vi>0 then + chr.italic=vi*hdelta + end + else + end + elseif vi~=0 then + chr.italic=vi*hdelta + end + elseif hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + if haskerns then + local vk=character.kerns + if vk then + local s=sharedkerns[vk] + if not s then + s={} + for k,v in next,vk do s[k]=v*hdelta end + sharedkerns[vk]=s + end + chr.kerns=s + end + end + if hasligatures then + local vl=character.ligatures + if vl then + if true then + chr.ligatures=vl + else + local tt={} + for i,l in next,vl do + tt[i]=l + end + chr.ligatures=tt + end + end + end + if isvirtual then + local vc=character.commands + if vc then + local ok=false + for i=1,#vc do + local key=vc[i][1] + if key=="right" or key=="down" or key=="rule" then + ok=true + break + end + end + if ok then + local tt={} + for i=1,#vc do + local ivc=vc[i] + local key=ivc[1] + if key=="right" then + tt[i]={ key,ivc[2]*hdelta } + elseif key=="down" then + tt[i]={ key,ivc[2]*vdelta } + elseif key=="rule" then + tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } + else + tt[i]=ivc + end + end + chr.commands=tt + else + chr.commands=vc + end + end + end + targetcharacters[unicode]=chr + end + properties.setitalics=hasitalics + constructors.aftercopyingcharacters(target,tfmdata) + constructors.trytosharefont(target,tfmdata) + local vfonts=target.fonts + if isvirtual or target.type=="virtual" or properties.virtualized then + properties.virtualized=true + target.type="virtual" + if not vfonts or #vfonts==0 then + target.fonts={ { id=0 } } + end + elseif vfonts then + properties.virtualized=true + target.type="virtual" + if #vfonts==0 then + target.fonts={ { id=0 } } + end + end + return target +end +function constructors.finalize(tfmdata) + if tfmdata.properties and tfmdata.properties.finalized then + return + end + if not tfmdata.characters then + return nil + end + if not tfmdata.goodies then + tfmdata.goodies={} + end + local parameters=tfmdata.parameters + if not parameters then + return nil + end + if not parameters.expansion then + parameters.expansion={ + stretch=tfmdata.stretch or 0, + shrink=tfmdata.shrink or 0, + step=tfmdata.step or 0, + } + end + if not parameters.size then + parameters.size=tfmdata.size + end + if not parameters.mode then + parameters.mode=0 + end + if not parameters.width then + parameters.width=0 + end + if not parameters.slantfactor then + parameters.slantfactor=(tfmdata.slant or 0)/1000 + end + if not parameters.extendfactor then + parameters.extendfactor=(tfmdata.extend or 1000)/1000 + end + if not parameters.squeezefactor then + parameters.squeezefactor=(tfmdata.squeeze or 1000)/1000 + end + local designsize=parameters.designsize + if designsize then + parameters.minsize=tfmdata.minsize or designsize + parameters.maxsize=tfmdata.maxsize or designsize + else + designsize=factors.pt*10 + parameters.designsize=designsize + parameters.minsize=designsize + parameters.maxsize=designsize + end + parameters.minsize=tfmdata.minsize or parameters.designsize + parameters.maxsize=tfmdata.maxsize or parameters.designsize + if not parameters.units then + parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 + end + if not tfmdata.descriptions then + local descriptions={} + setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) + tfmdata.descriptions=descriptions + end + local properties=tfmdata.properties + if not properties then + properties={} + tfmdata.properties=properties + end + if not properties.virtualized then + properties.virtualized=tfmdata.type=="virtual" + end + properties.fontname=properties.fontname or tfmdata.fontname + properties.filename=properties.filename or tfmdata.filename + properties.fullname=properties.fullname or tfmdata.fullname + properties.name=properties.name or tfmdata.name + properties.psname=properties.psname or tfmdata.psname + properties.encodingbytes=tfmdata.encodingbytes or 1 + properties.subfont=tfmdata.subfont or nil + properties.embedding=tfmdata.embedding or "subset" + properties.tounicode=tfmdata.tounicode or 1 + properties.cidinfo=tfmdata.cidinfo or nil + properties.format=tfmdata.format or "type1" + properties.direction=tfmdata.direction or 0 + properties.writingmode=tfmdata.writingmode or "horizontal" + properties.identity=tfmdata.identity or "horizontal" + properties.usedbitmap=tfmdata.usedbitmap + if not tfmdata.resources then + tfmdata.resources={} + end + if not tfmdata.shared then + tfmdata.shared={} + end + if not properties.hasmath then + properties.hasmath=not tfmdata.nomath + end + tfmdata.MathConstants=nil + tfmdata.postprocessors=nil + tfmdata.fontname=nil + tfmdata.filename=nil + tfmdata.fullname=nil + tfmdata.name=nil + tfmdata.psname=nil + tfmdata.encodingbytes=nil + tfmdata.subfont=nil + tfmdata.embedding=nil + tfmdata.tounicode=nil + tfmdata.cidinfo=nil + tfmdata.format=nil + tfmdata.direction=nil + tfmdata.type=nil + tfmdata.nomath=nil + tfmdata.designsize=nil + tfmdata.size=nil + tfmdata.stretch=nil + tfmdata.shrink=nil + tfmdata.step=nil + tfmdata.slant=nil + tfmdata.extend=nil + tfmdata.squeeze=nil + tfmdata.mode=nil + tfmdata.width=nil + tfmdata.units=nil + tfmdata.units_per_em=nil + tfmdata.cache=nil + properties.finalized=true + return tfmdata +end +local hashmethods={} +constructors.hashmethods=hashmethods +function constructors.hashfeatures(specification) + local features=specification.features + if features then + local t,n={},0 + for category,list in sortedhash(features) do + if next(list) then + local hasher=hashmethods[category] + if hasher then + local hash=hasher(list) + if hash then + n=n+1 + t[n]=category..":"..hash + end + end + end + end + if n>0 then + return concat(t," & ") + end + end + return "unknown" +end +hashmethods.normal=function(list) + local s={} + local n=0 + for k,v in next,list do + if not k then + elseif k=="number" or k=="features" then + else + n=n+1 + if type(v)=="table" then + local t={} + local m=0 + for k,v in next,v do + m=m+1 + t[m]=k..'='..tostring(v) + end + sort(t) + s[n]=k..'={'..concat(t,",").."}" + else + s[n]=k..'='..tostring(v) + end + end + end + if n>0 then + sort(s) + return concat(s,"+") + end +end +function constructors.hashinstance(specification,force) + local hash=specification.hash + local size=specification.size + local fallbacks=specification.fallbacks + if force or not hash then + hash=constructors.hashfeatures(specification) + specification.hash=hash + end + if size<1000 and designsizes[hash] then + size=round(constructors.scaled(size,designsizes[hash])) + else + size=round(size) + end + specification.size=size + if fallbacks then + return hash..' @ '..size..' @ '..fallbacks + else + return hash..' @ '..size + end +end +function constructors.setname(tfmdata,specification) + if constructors.namemode=="specification" then + local specname=specification.specification + if specname then + tfmdata.properties.name=specname + if trace_defining then + report_otf("overloaded fontname %a",specname) + end + end + end +end +function constructors.checkedfilename(data) + local foundfilename=data.foundfilename + if not foundfilename then + local askedfilename=data.filename or "" + if askedfilename~="" then + askedfilename=resolvers.resolve(askedfilename) + foundfilename=resolvers.findbinfile(askedfilename,"") or "" + if foundfilename=="" then + report_defining("source file %a is not found",askedfilename) + foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" + if foundfilename~="" then + report_defining("using source file %a due to cache mismatch",foundfilename) + end + end + end + data.foundfilename=foundfilename + end + return foundfilename +end +local formats=allocate() +fonts.formats=formats +setmetatableindex(formats,function(t,k) + local l=lower(k) + if rawget(t,k) then + t[k]=l + return l + end + return rawget(t,file.suffix(l)) +end) +do + local function setindeed(mode,source,target,group,name,position) + local action=source[mode] + if not action then + return + end + local t=target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + insert(t,position,{ name=name,action=action }) + else + for i=1,#t do + local ti=t[i] + if ti.name==name then + ti.action=action + return + end + end + insert(t,{ name=name,action=action }) + end + end + local function set(group,name,target,source) + target=target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() + end + local source=source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() + end + local position=source.position + setindeed("node",source,target,group,name,position) + setindeed("base",source,target,group,name,position) + setindeed("plug",source,target,group,name,position) + end + local function register(where,specification) + local name=specification.name + if name and name~="" then + local default=specification.default + local description=specification.description + local initializers=specification.initializers + local processors=specification.processors + local manipulators=specification.manipulators + local modechecker=specification.modechecker + if default then + where.defaults[name]=default + end + if description and description~="" then + where.descriptions[name]=description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors',name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker=modechecker + end + end + end + constructors.registerfeature=register + function constructors.getfeatureaction(what,where,mode,name) + what=handlers[what].features + if what then + where=what[where] + if where then + mode=where[mode] + if mode then + for i=1,#mode do + local m=mode[i] + if m.name==name then + return m.action + end + end + end + end + end + end + local newfeatures={} + constructors.newfeatures=newfeatures + constructors.features=newfeatures + local function setnewfeatures(what) + local handler=handlers[what] + local features=handler.features + if not features then + local tables=handler.tables + local statistics=handler.statistics + features=allocate { + defaults={}, + descriptions=tables and tables.features or {}, + used=statistics and statistics.usedfeatures or {}, + initializers={ base={},node={},plug={} }, + processors={ base={},node={},plug={} }, + manipulators={ base={},node={},plug={} }, + } + features.register=function(specification) return register(features,specification) end + handler.features=features + end + return features + end + setmetatable(newfeatures,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, + }) +end +do + local newhandler={} + constructors.handlers=newhandler + constructors.newhandler=newhandler + local function setnewhandler(what) + local handler=handlers[what] + if not handler then + handler={} + handlers[what]=handler + end + return handler + end + setmetatable(newhandler,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, + }) +end +do + local newenhancer={} + constructors.enhancers=newenhancer + constructors.newenhancer=newenhancer + local function setnewenhancer(format) + local handler=handlers[format] + local enhancers=handler.enhancers + if not enhancers then + local actions=allocate() + local before=allocate() + local after=allocate() + local order=allocate() + local known={} + local nofsteps=0 + local patches={ before=before,after=after } + local trace=false + local report=logs.reporter("fonts",format.." enhancing") + trackers.register(format..".loading",function(v) trace=v end) + local function enhance(name,data,filename,raw) + local enhancer=actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + end + end + local function apply(data,filename,raw) + local basename=file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() + for e=1,nofsteps do + local enhancer=order[e] + local b=before[enhancer] + if b then + for pattern,action in next,b do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + enhance(enhancer,data,filename,raw) + local a=after[enhancer] + if a then + for pattern,action in next,a do + if find(basename,pattern) then + action(data,filename,raw) + end + end + end + ioflush() + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() + end + local function register(what,action) + if action then + if actions[what] then + else + nofsteps=nofsteps+1 + order[nofsteps]=what + known[what]=nofsteps + end + actions[what]=action + else + report("bad enhancer %a",what) + end + end + local function patch(what,where,pattern,action) + local pw=patches[what] + if pw then + local ww=pw[where] + if ww then + ww[pattern]=action + else + pw[where]={ [pattern]=action } + if not known[where] then + nofsteps=nofsteps+1 + order[nofsteps]=where + known[where]=nofsteps + end + end + end + end + enhancers={ + register=register, + apply=apply, + patch=patch, + report=report, + patches={ + register=patch, + report=report, + }, + } + handler.enhancers=enhancers + end + return enhancers + end + setmetatable(newenhancer,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, + }) +end +function constructors.checkedfeatures(what,features) + local defaults=handlers[what].features.defaults + if features and next(features) then + features=fastcopy(features) + for key,value in next,defaults do + if features[key]==nil then + features[key]=value + end + end + return features + else + return fastcopy(defaults) + end +end +function constructors.initializefeatures(what,tfmdata,features,trace,report) + if features and next(features) then + local properties=tfmdata.properties or {} + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmodechecker=whatfeatures.modechecker + local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" + properties.mode=mode + features.mode=mode + local done={} + while true do + local redo=false + local initializers=whatfeatures.initializers[mode] + if initializers then + for i=1,#initializers do + local step=initializers[i] + local feature=step.name + local value=features[feature] + if not value then + elseif done[feature] then + else + local action=step.action + if trace then + report("initializing feature %a to %a for mode %a for font %a",feature, + value,mode,tfmdata.properties.fullname) + end + action(tfmdata,value,features) + if mode~=properties.mode or mode~=features.mode then + if whatmodechecker then + properties.mode=whatmodechecker(tfmdata,features,properties.mode) + features.mode=properties.mode + end + if mode~=properties.mode then + mode=properties.mode + redo=true + end + end + done[feature]=true + end + if redo then + break + end + end + if not redo then + break + end + else + break + end + end + properties.mode=mode + return true + else + return false + end +end +function constructors.collectprocessors(what,tfmdata,features,trace,report) + local processes={} + local nofprocesses=0 + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatprocessors=whatfeatures.processors + local mode=properties.mode + local processors=whatprocessors[mode] + if processors then + for i=1,#processors do + local step=processors[i] + local feature=step.name + if features[feature] then + local action=step.action + if trace then + report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) + end + if action then + nofprocesses=nofprocesses+1 + processes[nofprocesses]=action + end + end + end + elseif trace then + report("no feature processors for mode %a for font %a",mode,properties.fullname) + end + end + return processes +end +function constructors.applymanipulators(what,tfmdata,features,trace,report) + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmanipulators=whatfeatures.manipulators + local mode=properties.mode + local manipulators=whatmanipulators[mode] + if manipulators then + for i=1,#manipulators do + local step=manipulators[i] + local feature=step.name + local value=features[feature] + if value then + local action=step.action + if trace then + report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) + end + if action then + action(tfmdata,feature,value) + end + end + end + end + end +end +function constructors.addcoreunicodes(unicodes) + if not unicodes then + unicodes={} + end + unicodes.space=0x0020 + unicodes.hyphen=0x002D + unicodes.zwj=0x200D + unicodes.zwnj=0x200C + return unicodes +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] --- + +if not modules then modules={} end modules ['luatex-font-enc']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local fonts=fonts +local encodings={} +fonts.encodings=encodings +encodings.agl={} +encodings.known={} +setmetatable(encodings.agl,{ __index=function(t,k) + if k=="unicodes" then + logs.report("fonts","loading (extended) adobe glyph list") + local unicodes=dofile(resolvers.findfile("font-age.lua")) + encodings.agl={ unicodes=unicodes } + return unicodes + else + return nil + end +end }) +encodings.cache=containers.define("fonts","enc",encodings.version,true) +function encodings.load(filename) + local name=file.removesuffix(filename) + local data=containers.read(encodings.cache,name) + if data then + return data + end + local vector,tag,hash,unicodes={},"",{},{} + local foundname=resolvers.findfile(filename,'enc') + if foundname and foundname~="" then + local ok,encoding,size=resolvers.loadbinfile(foundname) + if ok and encoding then + encoding=string.gsub(encoding,"%%(.-)\n","") + local unicoding=encodings.agl.unicodes + local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i=0 + for ch in string.gmatch(vec,"/([%a%d%.]+)") do + if ch~=".notdef" then + vector[i]=ch + if not hash[ch] then + hash[ch]=i + else + end + local u=unicoding[ch] + if u then + unicodes[u]=i + end + end + i=i+1 + end + end + end + local data={ + name=name, + tag=tag, + vector=vector, + hash=hash, + unicodes=unicodes + } + return containers.write(encodings.cache,name,data) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] --- + +if not modules then modules={} end modules ['font-cid']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local format,match,lower=string.format,string.match,string.lower +local tonumber=tonumber +local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match +local fonts,logs,trackers=fonts,logs,trackers +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local cid={} +fonts.cid=cid +local cidmap={} +local cidmax=10 +local number=C(R("09","af","AF")^1) +local space=S(" \n\r\t") +local spaces=space^0 +local period=P(".") +local periods=period*period +local name=P("/")*C((1-space)^1) +local unicodes,names={},{} +local function do_one(a,b) + unicodes[tonumber(a)]=tonumber(b,16) +end +local function do_range(a,b,c) + c=tonumber(c,16) + for i=tonumber(a),tonumber(b) do + unicodes[i]=c + c=c+1 + end +end +local function do_name(a,b) + names[tonumber(a)]=b +end +local grammar=P { "start", + start=number*spaces*number*V("series"), + series=(spaces*(V("one")+V("range")+V("named")))^1, + one=(number*spaces*number)/do_one, + range=(number*periods*number*spaces*number)/do_range, + named=(number*spaces*name)/do_name +} +local function loadcidfile(filename) + local data=io.loaddata(filename) + if data then + unicodes,names={},{} + lpegmatch(grammar,data) + local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") + return { + supplement=supplement, + registry=registry, + ordering=ordering, + filename=filename, + unicodes=unicodes, + names=names, + } + end +end +cid.loadfile=loadcidfile +local template="%s-%s-%s.cidmap" +local function locate(registry,ordering,supplement) + local filename=format(template,registry,ordering,supplement) + local hashname=lower(filename) + local found=cidmap[hashname] + if not found then + if trace_loading then + report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) + end + local fullname=resolvers.findfile(filename,'cid') or "" + if fullname~="" then + found=loadcidfile(fullname) + if found then + if trace_loading then + report_otf("using cidmap file %a",filename) + end + cidmap[hashname]=found + found.usedname=file.basename(filename) + end + end + end + return found +end +function cid.getmap(specification) + if not specification then + report_otf("invalid cidinfo specification, table expected") + return + end + local registry=specification.registry + local ordering=specification.ordering + local supplement=specification.supplement + local filename=format(registry,ordering,supplement) + local lowername=lower(filename) + local found=cidmap[lowername] + if found then + return found + end + if ordering=="Identity" then + local found={ + supplement=supplement, + registry=registry, + ordering=ordering, + filename=filename, + unicodes={}, + names={}, + } + cidmap[lowername]=found + return found + end + if trace_loading then + report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement) + end + found=locate(registry,ordering,supplement) + if not found then + local supnum=tonumber(supplement) + local cidnum=nil + if supnum0 then + for s=supnum-1,0,-1 do + local c=locate(registry,ordering,s) + if c then + found,cidnum=c,s + break + end + end + end + registry=lower(registry) + ordering=lower(ordering) + if found and cidnum>0 then + for s=0,cidnum-1 do + local filename=format(template,registry,ordering,s) + if not cidmap[filename] then + cidmap[filename]=found + end + end + end + end + return found +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] --- + +if not modules then modules={} end modules ['font-map']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tonumber,next,type=tonumber,next,type +local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower +local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match +local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys +local idiv=number.idiv +local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) +local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) +local report_fonts=logs.reporter("fonts","loading") +local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) +local fonts=fonts or {} +local mappings=fonts.mappings or {} +fonts.mappings=mappings +local allocate=utilities.storage.allocate +local hex=R("AF","af","09") +local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end +local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end +local dec=(R("09")^1)/tonumber +local period=P(".") +local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) +local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) +local index=P("index")*dec*Cc(false) +local parser=unicode+ucode+index +local parsers={} +local function makenameparser(str) + if not str or str=="" then + return parser + else + local p=parsers[str] + if not p then + p=P(str)*period*dec*Cc(false) + parsers[str]=p + end + return p + end +end +local f_single=formatters["%04X"] +local f_double=formatters["%04X%04X"] +local s_unknown="FFFD" +local function tounicode16(unicode) + if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then + return f_single(unicode) + elseif unicode>=0x00E000 and unicode<=0x00F8FF then + return s_unknown + elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then + return s_unknown + elseif unicode>=0x100000 and unicode<=0x10FFFF then + return s_unknown + elseif unicode>=0x00D800 and unicode<=0x00DFFF then + return s_unknown + else + unicode=unicode-0x10000 + return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00) + end +end +local function tounicode16sequence(unicodes) + local t={} + for l=1,#unicodes do + local u=unicodes[l] + if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then + t[l]=f_single(u) + elseif unicode>=0x00E000 and unicode<=0x00F8FF then + t[l]=s_unknown + elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then + t[l]=s_unknown + elseif unicode>=0x100000 and unicode<=0x10FFFF then + t[l]=s_unknown + elseif unicode>=0x00D7FF and unicode<=0x00DFFF then + t[l]=s_unknown + else + u=u-0x10000 + t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00) + end + end + return concat(t) +end +local hash={} +local conc={} +table.setmetatableindex(hash,function(t,k) + local v + if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then + v=f_single(k) + else + local k=k-0x10000 + v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00) + end + t[k]=v + return v +end) +local function tounicode(k) + if type(k)=="table" then + local n=#k + for l=1,n do + conc[l]=hash[k[l]] + end + return concat(conc,"",1,n) + elseif k>=0x00E000 and k<=0x00F8FF then + return s_unknown + elseif k>=0x0F0000 and k<=0x0FFFFF then + return s_unknown + elseif k>=0x100000 and k<=0x10FFFF then + return s_unknown + elseif k>=0x00D7FF and k<=0x00DFFF then + return s_unknown + else + return hash[k] + end +end +local function fromunicode16(str) + if #str==4 then + return tonumber(str,16) + else + local l,r=match(str,"(....)(....)") + return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 + end +end +mappings.makenameparser=makenameparser +mappings.tounicode=tounicode +mappings.tounicode16=tounicode16 +mappings.tounicode16sequence=tounicode16sequence +mappings.fromunicode16=fromunicode16 +local ligseparator=P("_") +local varseparator=P(".") +local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) +do + local overloads={ + IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, + ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, + ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, + fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, + fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, + ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, + ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, + fj={ name="f_j",unicode={ 0x66,0x6A } }, + fk={ name="f_k",unicode={ 0x66,0x6B } }, + } + local o=allocate {} + for k,v in next,overloads do + local name=v.name + local mess=v.mess + if name then + o[name]=v + end + if mess then + o[mess]=v + end + o[k]=v + end + mappings.overloads=o +end +function mappings.addtounicode(data,filename,checklookups,forceligatures) + local resources=data.resources + local unicodes=resources.unicodes + if not unicodes then + if trace_mapping then + report_fonts("no unicode list, quitting tounicode for %a",filename) + end + return + end + local properties=data.properties + local descriptions=data.descriptions + local overloads=mappings.overloads + unicodes['space']=unicodes['space'] or 32 + unicodes['hyphen']=unicodes['hyphen'] or 45 + unicodes['zwj']=unicodes['zwj'] or 0x200D + unicodes['zwnj']=unicodes['zwnj'] or 0x200C + local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 + local unicodevector=fonts.encodings.agl.unicodes or {} + local contextvector=fonts.encodings.agl.ctxcodes or {} + local missing={} + local nofmissing=0 + local oparser=nil + local cidnames=nil + local cidcodes=nil + local cidinfo=properties.cidinfo + local usedmap=cidinfo and fonts.cid.getmap(cidinfo) + local uparser=makenameparser() + if usedmap then + oparser=usedmap and makenameparser(cidinfo.ordering) + cidnames=usedmap.names + cidcodes=usedmap.unicodes + end + local ns=0 + local nl=0 + local dlist=sortedkeys(descriptions) + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name + if name then + local overload=overloads[name] or overloads[du] + if overload then + glyph.unicode=overload.unicode + else + local gu=glyph.unicode + if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then + local unicode=unicodevector[name] or contextvector[name] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + if (not unicode) and usedmap then + local foundindex=lpegmatch(oparser,name) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + else + local reference=cidnames[foundindex] + if reference then + local foundindex=lpegmatch(oparser,reference) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,reference) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end + end + end + end + end + end + end + if not unicode or unicode=="" then + local split=lpegmatch(namesplitter,name) + local nsplit=split and #split or 0 + if nsplit==0 then + elseif nsplit==1 then + local base=split[1] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + elseif type(u)=="table" then + if u[1]=private then + break + end + n=n+1 + t[n]=u[1] + else + if u>=private then + break + end + n=n+1 + t[n]=u + end + end + if n>0 then + if n==1 then + unicode=t[1] + else + unicode=t + end + glyph.unicode=unicode + end + end + nl=nl+1 + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,name) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end + end + end + local r=overloads[unicode] + if r then + unicode=r.unicode + glyph.unicode=unicode + end + if not unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + else + end + end + else + local overload=overloads[du] + if overload then + glyph.unicode=overload.unicode + elseif not glyph.unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + end + end + if type(checklookups)=="function" then + checklookups(data,missing,nofmissing) + end + local unicoded=0 + local collected=fonts.handlers.otf.readers.getcomponents(data) + local function resolve(glyph,u) + local n=#u + for i=1,n do + if u[i]>private then + n=0 + break + end + end + if n>0 then + if n>1 then + glyph.unicode=u + else + glyph.unicode=u[1] + end + unicoded=unicoded+1 + end + end + if not collected then + elseif forceligatures or force_ligatures then + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local u=collected[du] + if u then + resolve(descriptions[du],u) + end + end + end + else + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local glyph=descriptions[du] + if glyph.class=="ligature" and not glyph.unicode then + local u=collected[du] + if u then + resolve(glyph,u) + end + end + end + end + end + if trace_mapping and unicoded>0 then + report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) + end + if trace_mapping then + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name or "-" + local index=glyph.index or 0 + local unicode=glyph.unicode + if unicode then + if type(unicode)=="table" then + local unicodes={} + for i=1,#unicode do + unicodes[i]=formatters("%U",unicode[i]) + end + report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) + else + report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) + end + else + report_fonts("internal slot %U, name %a, unicode %U",index,name,du) + end + end + end + if trace_loading and (ns>0 or nl>0) then + report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] --- + +if not modules then modules={} end modules ['font-vfc']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local select,type=select,type +local insert=table.insert +local fonts=fonts +local helpers=fonts.helpers +local setmetatableindex=table.setmetatableindex +local push={ "push" } +local pop={ "pop" } +local dummy={ "comment" } +function helpers.prependcommands(commands,...) + insert(commands,1,push) + for i=select("#",...),1,-1 do + local s=(select(i,...)) + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end +function helpers.appendcommands(commands,...) + insert(commands,1,push) + insert(commands,pop) + for i=1,select("#",...) do + local s=(select(i,...)) + if s then + insert(commands,s) + end + end + return commands +end +function helpers.prependcommandtable(commands,t) + insert(commands,1,push) + for i=#t,1,-1 do + local s=t[i] + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end +function helpers.appendcommandtable(commands,t) + insert(commands,1,push) + insert(commands,pop) + for i=1,#t do + local s=t[i] + if s then + insert(commands,s) + end + end + return commands +end +local char=setmetatableindex(function(t,k) + local v={ "slot",0,k } + t[k]=v + return v +end) +local right=setmetatableindex(function(t,k) + local v={ "right",k } + t[k]=v + return v +end) +local left=setmetatableindex(function(t,k) + local v={ "right",-k } + t[k]=v + return v +end) +local down=setmetatableindex(function(t,k) + local v={ "down",k } + t[k]=v + return v +end) +local up=setmetatableindex(function(t,k) + local v={ "down",-k } + t[k]=v + return v +end) +helpers.commands=utilities.storage.allocate { + char=char, + right=right, + left=left, + down=down, + up=up, + push=push, + pop=pop, + dummy=dummy, +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr” 64dcbbc7107538723990e1119a80a9f8] --- + +if not modules then modules={} end modules ['font-otr']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber,rawget=next,type,tonumber,rawget +local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub +local fullstrip=string.fullstrip +local floor,round=math.floor,math.round +local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt +local lpegmatch=lpeg.match +local rshift=bit32.rshift +local setmetatableindex=table.setmetatableindex +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local stripstring=string.nospaces +local utf16_to_utf8_be=utf.utf16_to_utf8_be +local report=logs.reporter("otf reader") +local report_cmap=logs.reporter("otf reader","cmap") +local trace_cmap=false trackers.register("otf.cmap",function(v) trace_cmap=v end) +local trace_cmap_details=false trackers.register("otf.cmap.details",function(v) trace_cmap_details=v end) +fonts=fonts or {} +local handlers=fonts.handlers or {} +fonts.handlers=handlers +local otf=handlers.otf or {} +handlers.otf=otf +local readers=otf.readers or {} +otf.readers=readers +local streamreader=utilities.files +local streamwriter=utilities.files +readers.streamreader=streamreader +readers.streamwriter=streamwriter +local openfile=streamreader.open +local closefile=streamreader.close +local setposition=streamreader.setposition +local skipshort=streamreader.skipshort +local readbytes=streamreader.readbytes +local readstring=streamreader.readstring +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 +local readulong=streamreader.readcardinal4 +local readshort=streamreader.readinteger2 +local readlong=streamreader.readinteger4 +local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 +local readfword=readshort +local readufword=readushort +local readoffset=readushort +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) +end +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + openfile=streamreader.open + closefile=streamreader.close + setposition=streamreader.setposition + skipshort=streamreader.skipshort + readbytes=streamreader.readbytes + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + readshort=streamreader.readinteger2 + readlong=streamreader.readinteger4 + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + readfword=readshort + readufword=readushort + readoffset=readushort + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) + end +end) +local function readlongdatetime(f) + local a,b,c,d,e,f,g,h=readbytes(f,8) + return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h +end +local tableversion=0.004 +readers.tableversion=tableversion +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local reservednames={ [0]="copyright", + "family", + "subfamily", + "uniqueid", + "fullname", + "version", + "postscriptname", + "trademark", + "manufacturer", + "designer", + "description", + "vendorurl", + "designerurl", + "license", + "licenseurl", + "reserved", + "typographicfamily", + "typographicsubfamily", + "compatiblefullname", + "sampletext", + "cidfindfontname", + "wwsfamily", + "wwssubfamily", + "lightbackgroundpalette", + "darkbackgroundpalette", + "variationspostscriptnameprefix", +} +local platforms={ [0]="unicode", + "macintosh", + "iso", + "windows", + "custom", +} +local encodings={ + unicode={ [0]="unicode 1.0 semantics", + "unicode 1.1 semantics", + "iso/iec 10646", + "unicode 2.0 bmp", + "unicode 2.0 full", + "unicode variation sequences", + "unicode full repertoire", + }, + macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", + "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", + "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", + "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", + "uninterpreted", + }, + iso={ [0]="7-bit ascii", + "iso 10646", + "iso 8859-1", + }, + windows={ [0]="symbol", + "unicode bmp", + "shiftjis", + "prc", + "big5", + "wansung", + "johab", + "reserved 7", + "reserved 8", + "reserved 9", + "unicode ucs-4", + }, + custom={ + } +} +local decoders={ + unicode={}, + macintosh={}, + iso={}, + windows={ + ["unicode semantics"]=utf16_to_utf8_be, + ["unicode bmp"]=utf16_to_utf8_be, + ["unicode full"]=utf16_to_utf8_be, + ["unicode 1.0 semantics"]=utf16_to_utf8_be, + ["unicode 1.1 semantics"]=utf16_to_utf8_be, + ["unicode 2.0 bmp"]=utf16_to_utf8_be, + ["unicode 2.0 full"]=utf16_to_utf8_be, + ["unicode variation sequences"]=utf16_to_utf8_be, + ["unicode full repertoire"]=utf16_to_utf8_be, + }, + custom={}, +} +local languages={ + unicode={ + [ 0]="english", + }, + macintosh={ + [ 0]="english", + }, + iso={}, + windows={ + [0x0409]="english - united states", + }, + custom={}, +} +local standardromanencoding={ [0]= + "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", + "numbersign","dollar","percent","ampersand","quotesingle","parenleft", + "parenright","asterisk","plus","comma","hyphen","period","slash", + "zero","one","two","three","four","five","six","seven","eight", + "nine","colon","semicolon","less","equal","greater","question","at", + "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", + "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", + "backslash","bracketright","asciicircum","underscore","grave","a","b", + "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", + "r","s","t","u","v","w","x","y","z","braceleft","bar", + "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", + "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", + "adieresis","atilde","aring","ccedilla","eacute","egrave", + "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", + "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", + "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", + "section","bullet","paragraph","germandbls","registered","copyright", + "trademark","acute","dieresis","notequal","AE","Oslash","infinity", + "plusminus","lessequal","greaterequal","yen","mu","partialdiff", + "summation","product","pi","integral","ordfeminine","ordmasculine", + "Omega","ae","oslash","questiondown","exclamdown","logicalnot", + "radical","florin","approxequal","Delta","guillemotleft", + "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", + "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", + "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", + "fraction","currency","guilsinglleft","guilsinglright","fi","fl", + "daggerdbl","periodcentered","quotesinglbase","quotedblbase", + "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", + "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", + "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", + "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", + "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", + "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", + "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", + "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", + "dcroat", +} +local weights={ + [100]="thin", + [200]="extralight", + [300]="light", + [400]="normal", + [500]="medium", + [600]="semibold", + [700]="bold", + [800]="extrabold", + [900]="black", +} +local widths={ + [1]="ultracondensed", + [2]="extracondensed", + [3]="condensed", + [4]="semicondensed", + [5]="normal", + [6]="semiexpanded", + [7]="expanded", + [8]="extraexpanded", + [9]="ultraexpanded", +} +setmetatableindex(weights,function(t,k) + local r=floor((k+50)/100)*100 + local v=(r>900 and "black") or rawget(t,r) or "normal" + return v +end) +setmetatableindex(widths,function(t,k) + return "normal" +end) +local panoseweights={ + [ 0]="normal", + [ 1]="normal", + [ 2]="verylight", + [ 3]="light", + [ 4]="thin", + [ 5]="book", + [ 6]="medium", + [ 7]="demi", + [ 8]="bold", + [ 9]="heavy", + [10]="black", +} +local panosewidths={ + [ 0]="normal", + [ 1]="normal", + [ 2]="normal", + [ 3]="normal", + [ 4]="normal", + [ 5]="expanded", + [ 6]="condensed", + [ 7]="veryexpanded", + [ 8]="verycondensed", + [ 9]="monospaced", +} +local helpers={} +readers.helpers=helpers +local function gotodatatable(f,fontdata,tag,criterium) + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + return tableoffset + end + else + report("no tables") + end + end +end +local function reportskippedtable(f,fontdata,tag,criterium) + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + else + report("no tables") + end + end +end +local function setvariabledata(fontdata,tag,data) + local variabledata=fontdata.variabledata + if variabledata then + variabledata[tag]=data + else + fontdata.variabledata={ [tag]=data } + end +end +helpers.gotodatatable=gotodatatable +helpers.setvariabledata=setvariabledata +helpers.reportskippedtable=reportskippedtable +local platformnames={ + postscriptname=true, + fullname=true, + family=true, + subfamily=true, + typographicfamily=true, + typographicsubfamily=true, + compatiblefullname=true, +} +local platformextras={ + uniqueid=true, + version=true, + copyright=true, + license=true, + licenseurl=true, + manufacturer=true, + vendorurl=true, +} +function readers.name(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"name",true) + if tableoffset then + local format=readushort(f) + local nofnames=readushort(f) + local offset=readushort(f) + local start=tableoffset+offset + local namelists={ + unicode={}, + windows={}, + macintosh={}, + } + for i=1,nofnames do + local platform=platforms[readushort(f)] + if platform then + local namelist=namelists[platform] + if namelist then + local encoding=readushort(f) + local language=readushort(f) + local encodings=encodings[platform] + local languages=languages[platform] + if encodings and languages then + local encoding=encodings[encoding] + local language=languages[language] + if encoding and language then + local index=readushort(f) + local name=reservednames[index] + namelist[#namelist+1]={ + platform=platform, + encoding=encoding, + language=language, + name=name, + index=index, + length=readushort(f), + offset=start+readushort(f), + } + else + skipshort(f,3) + end + else + skipshort(f,3) + end + else + skipshort(f,5) + end + else + skipshort(f,5) + end + end + local names={} + local done={} + local extras={} + local function decoded(platform,encoding,content) + local decoder=decoders[platform] + if decoder then + decoder=decoder[encoding] + end + if decoder then + return decoder(content) + else + return content + end + end + local function filter(platform,e,l) + local namelist=namelists[platform] + for i=1,#namelist do + local name=namelist[i] + local nametag=name.name + local index=name.index + if not done[nametag or i] then + local encoding=name.encoding + local language=name.language + if (not e or encoding==e) and (not l or language==l) then + setposition(f,name.offset) + local content=decoded(platform,encoding,readstring(f,name.length)) + if nametag then + names[nametag]={ + content=content, + platform=platform, + encoding=encoding, + language=language, + } + end + extras[index]=content + done[nametag or i]=true + end + end + end + end + filter("windows","unicode bmp","english - united states") + filter("macintosh","roman","english") + filter("windows") + filter("macintosh") + filter("unicode") + fontdata.names=names + fontdata.extras=extras + if specification.platformnames then + local collected={} + local platformextras=specification.platformextras and platformextras + for platform,namelist in next,namelists do + local filtered=false + for i=1,#namelist do + local entry=namelist[i] + local name=entry.name + if platformnames[name] or (platformextras and platformextras[name]) then + setposition(f,entry.offset) + local content=decoded(platform,entry.encoding,readstring(f,entry.length)) + if filtered then + filtered[name]=content + else + filtered={ [name]=content } + end + end + end + if filtered then + collected[platform]=filtered + end + end + fontdata.platformnames=collected + end + else + fontdata.names={} + end +end +local validutf=lpeg.patterns.validutf8 +local function getname(fontdata,key) + local names=fontdata.names + if names then + local value=names[key] + if value then + local content=value.content + return lpegmatch(validutf,content) and content or nil + end + end +end +readers["os/2"]=function(f,fontdata) + local tableoffset=gotodatatable(f,fontdata,"os/2",true) + if tableoffset then + local version=readushort(f) + local windowsmetrics={ + version=version, + averagewidth=readshort(f), + weightclass=readushort(f), + widthclass=readushort(f), + fstype=readushort(f), + subscriptxsize=readshort(f), + subscriptysize=readshort(f), + subscriptxoffset=readshort(f), + subscriptyoffset=readshort(f), + superscriptxsize=readshort(f), + superscriptysize=readshort(f), + superscriptxoffset=readshort(f), + superscriptyoffset=readshort(f), + strikeoutsize=readshort(f), + strikeoutpos=readshort(f), + familyclass=readshort(f), + panose={ readbytes(f,10) }, + unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, + vendor=readstring(f,4), + fsselection=readushort(f), + firstcharindex=readushort(f), + lastcharindex=readushort(f), + typoascender=readshort(f), + typodescender=readshort(f), + typolinegap=readshort(f), + winascent=readushort(f), + windescent=readushort(f), + } + if version>=1 then + windowsmetrics.codepageranges={ readulong(f),readulong(f) } + end + if version>=2 then + windowsmetrics.xheight=readshort(f) + windowsmetrics.capheight=readshort(f) + windowsmetrics.defaultchar=readushort(f) + windowsmetrics.breakchar=readushort(f) + end + windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] + windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] + windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] + windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] + fontdata.windowsmetrics=windowsmetrics + else + fontdata.windowsmetrics={} + end +end +readers.head=function(f,fontdata) + local tableoffset=gotodatatable(f,fontdata,"head",true) + if tableoffset then + local version=readulong(f) + local fontversion=readulong(f) + local fontheader={ + version=version, + fontversion=number.to16dot16(fontversion), + fontversionnumber=fontversion, + checksum=readushort(f)*0x10000+readushort(f), + magic=readulong(f), + flags=readushort(f), + units=readushort(f), + created=readlongdatetime(f), + modified=readlongdatetime(f), + xmin=readshort(f), + ymin=readshort(f), + xmax=readshort(f), + ymax=readshort(f), + macstyle=readushort(f), + smallpixels=readushort(f), + directionhint=readshort(f), + indextolocformat=readshort(f), + glyphformat=readshort(f), + } + fontdata.fontheader=fontheader + else + fontdata.fontheader={} + end + fontdata.nofglyphs=0 +end +readers.hhea=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) + if tableoffset then + fontdata.horizontalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvancewidth=readufword(f), + minleftsidebearing=readfword(f), + minrightsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.horizontalheader={ + nofmetrics=0, + } + end +end +readers.vhea=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) + if tableoffset then + fontdata.verticalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvanceheight=readufword(f), + mintopsidebearing=readfword(f), + minbottomsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.verticalheader={ + nofmetrics=0, + } + end +end +readers.maxp=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) + if tableoffset then + local version=readulong(f) + local nofglyphs=readushort(f) + fontdata.nofglyphs=nofglyphs + if version==0x00005000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + } + elseif version==0x00010000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + points=readushort(f), + contours=readushort(f), + compositepoints=readushort(f), + compositecontours=readushort(f), + zones=readushort(f), + twilightpoints=readushort(f), + storage=readushort(f), + functiondefs=readushort(f), + instructiondefs=readushort(f), + stackelements=readushort(f), + sizeofinstructions=readushort(f), + componentelements=readushort(f), + componentdepth=readushort(f), + } + else + fontdata.maximumprofile={ + version=version, + nofglyphs=0, + } + end + end +end +readers.hmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) + if tableoffset then + local horizontalheader=fontdata.horizontalheader + local nofmetrics=horizontalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local width=0 + local leftsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + width=readshort(f) + leftsidebearing=readshort(f) + if width~=0 then + glyph.width=width + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if width~=0 then + glyph.width=width + end + end + end +end +readers.vmtx=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) + if tableoffset then + local verticalheader=fontdata.verticalheader + local nofmetrics=verticalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local vheight=0 + local vdefault=verticalheader.ascender-verticalheader.descender + local topsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + vheight=readushort(f) + topsidebearing=readshort(f) + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + if topsidebearing~=0 then + glyph.tsb=topsidebearing + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + end + end +end +readers.vorg=function(f,fontdata,specification) + reportskippedtable(f,fontdata,"vorg",specification.glyphs) +end +readers.post=function(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"post",true) + if tableoffset then + local version=readulong(f) + fontdata.postscript={ + version=version, + italicangle=round(1000*readfixed(f))/1000, + underlineposition=readfword(f), + underlinethickness=readfword(f), + monospaced=readulong(f), + minmemtype42=readulong(f), + maxmemtype42=readulong(f), + minmemtype1=readulong(f), + maxmemtype1=readulong(f), + } + if not specification.glyphs then + elseif version==0x00010000 then + for index=0,#standardromanencoding do + glyphs[index].name=standardromanencoding[index] + end + elseif version==0x00020000 then + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local indices={} + local names={} + local maxnames=0 + for i=0,nofglyphs-1 do + local nameindex=readushort(f) + if nameindex>=258 then + maxnames=maxnames+1 + nameindex=nameindex-257 + indices[nameindex]=i + else + glyphs[i].name=standardromanencoding[nameindex] + end + end + for i=1,maxnames do + local mapping=indices[i] + if not mapping then + report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") + break + else + local length=readbyte(f) + if length>0 then + glyphs[mapping].name=readstring(f,length) + else + report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") + break + end + end + end + end + else + fontdata.postscript={} + end +end +readers.cff=function(f,fontdata,specification) + reportskippedtable(f,fontdata,"cff",specification.glyphs) +end +local formatreaders={} +local duplicatestoo=true +local sequence={ + { 3,1,4 }, + { 3,10,12 }, + { 0,3,4 }, + { 0,3,12 }, + { 0,1,4 }, + { 0,1,12 }, + { 0,0,6 }, + { 3,0,6 }, + { 3,0,4 }, + { 0,5,14 }, + { 0,4,12 }, + { 3,10,13 }, +} +local supported={} +for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + local p=supported[sp] + if not p then + p={} + supported[sp]=p + end + local e=p[se] + if not e then + e={} + p[se]=e + end + e[sf]=true +end +formatreaders[4]=function(f,fontdata,offset) + setposition(f,offset+2) + local length=readushort(f) + local language=readushort(f) + local nofsegments=readushort(f)/2 + skipshort(f,3) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofdone=0 + local endchars=readcardinaltable(f,nofsegments,ushort) + local reserved=readushort(f) + local startchars=readcardinaltable(f,nofsegments,ushort) + local deltas=readcardinaltable(f,nofsegments,ushort) + local offsets=readcardinaltable(f,nofsegments,ushort) + local size=(length-2*2-5*2-4*2*nofsegments)/2 + local indices=readcardinaltable(f,size-1,ushort) + for segment=1,nofsegments do + local startchar=startchars[segment] + local endchar=endchars[segment] + local offset=offsets[segment] + local delta=deltas[segment] + if startchar==0xFFFF and endchar==0xFFFF then + elseif startchar==0xFFFF and offset==0 then + elseif offset==0xFFFF then + elseif offset==0 then + if trace_cmap_details then + report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local index=(unicode+delta)%65536 + if index and index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + else + report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + else + local shift=(segment-nofsegments+offset/2)-startchar + if trace_cmap_details then + report_cmap("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local slot=shift+unicode + local index=indices[slot] + if index and index>0 then + index=(index+delta)%65536 + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + else + report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + end + end + return nofdone +end +formatreaders[6]=function(f,fontdata,offset) + setposition(f,offset) + local format=readushort(f) + local length=readushort(f) + local language=readushort(f) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local start=readushort(f) + local count=readushort(f) + local stop=start+count-1 + local nofdone=0 + if trace_cmap_details then + report_cmap("format 6 from %C to %C",2,start,stop) + end + for unicode=start,stop do + local index=readushort(f) + if index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + return nofdone +end +formatreaders[12]=function(f,fontdata,offset) + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if trace_cmap_details then + report_cmap("format 12 from %C to %C starts at index %i",first,last,index) + end + for unicode=first,last do + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end + end + if not mapping[index] then + mapping[index]=unicode + end + end + index=index+1 + end + end + return nofdone +end +formatreaders[13]=function(f,fontdata,offset) + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if first=privateoffset then + local limit=privateoffset-1 + report("format 13 from %C to %C pruned to %C",first,last,limit) + last=limit + end + for unicode=first,last do + list[unicode]=true + end + nofdone=nofdone+last-first+1 + else + report("format 13 from %C to %C ignored",first,last) + end + end + return nofdone +end +formatreaders[14]=function(f,fontdata,offset) + if offset and offset~=0 then + setposition(f,offset) + local format=readushort(f) + local length=readulong(f) + local nofrecords=readulong(f) + local records={} + local variants={} + local nofdone=0 + fontdata.variants=variants + for i=1,nofrecords do + records[i]={ + selector=readuint(f), + default=readulong(f), + other=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local selector=record.selector + local default=record.default + local other=record.other + local other=record.other + if other~=0 then + setposition(f,offset+other) + local mapping={} + local count=readulong(f) + for i=1,count do + mapping[readuint(f)]=readushort(f) + end + nofdone=nofdone+count + variants[selector]=mapping + end + end + return nofdone + else + return 0 + end +end +local function checkcmap(f,fontdata,records,platform,encoding,format) + local pdata=records[platform] + if not pdata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no platform",platform,encoding,format) + end + return 0 + end + local edata=pdata[encoding] + if not edata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no encoding",platform,encoding,format) + end + return 0 + end + local fdata=edata[format] + if not fdata then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","no format",platform,encoding,format) + end + return 0 + elseif type(fdata)~="number" then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","already done",platform,encoding,format) + end + return 0 + end + edata[format]=true + local reader=formatreaders[format] + if not reader then + if trace_cmap_details then + report_cmap("skipped, %s, p=%i e=%i f=%i","unsupported format",platform,encoding,format) + end + return 0 + end + local n=reader(f,fontdata,fdata) or 0 + if trace_cmap_details or trace_cmap then + local p=platforms[platform] + local e=encodings[p] + report_cmap("checked, platform %i (%s), encoding %i (%s), format %i, new unicodes %i", + platform,p,encoding,e and e[encoding] or "?",format,n) + end + return n +end +function readers.cmap(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + local records={} + local unicodecid=false + local variantcid=false + local variants={} + local duplicates=fontdata.duplicates or {} + fontdata.duplicates=duplicates + for i=1,noftables do + local platform=readushort(f) + local encoding=readushort(f) + local offset=readulong(f) + local record=records[platform] + if not record then + records[platform]={ + [encoding]={ + offsets={ offset }, + formats={}, + } + } + else + local subtables=record[encoding] + if not subtables then + record[encoding]={ + offsets={ offset }, + formats={}, + } + else + local offsets=subtables.offsets + offsets[#offsets+1]=offset + end + end + end + if trace_cmap then + report("found cmaps:") + end + for platform,record in sortedhash(records) do + local p=platforms[platform] + local e=encodings[p] + local sp=supported[platform] + local ps=p or "?" + if trace_cmap then + if sp then + report(" platform %i: %s",platform,ps) + else + report(" platform %i: %s (unsupported)",platform,ps) + end + end + for encoding,subtables in sortedhash(record) do + local se=sp and sp[encoding] + local es=e and e[encoding] or "?" + if trace_cmap then + if se then + report(" encoding %i: %s",encoding,es) + else + report(" encoding %i: %s (unsupported)",encoding,es) + end + end + local offsets=subtables.offsets + local formats=subtables.formats + for i=1,#offsets do + local offset=tableoffset+offsets[i] + setposition(f,offset) + formats[readushort(f)]=offset + end + record[encoding]=formats + if trace_cmap then + local list=sortedkeys(formats) + for i=1,#list do + if not (se and se[list[i]]) then + list[i]=list[i].." (unsupported)" + end + end + report(" formats: % t",list) + end + end + end + local ok=false + for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + if checkcmap(f,fontdata,records,sp,se,sf)>0 then + ok=true + end + end + if not ok then + report("no useable unicode cmap found") + end + fontdata.cidmaps={ + version=version, + noftables=noftables, + records=records, + } + else + fontdata.cidmaps={} + end +end +function readers.loca(f,fontdata,specification) + reportskippedtable(f,fontdata,"loca",specification.glyphs) +end +function readers.glyf(f,fontdata,specification) + reportskippedtable(f,fontdata,"glyf",specification.glyphs) +end +function readers.colr(f,fontdata,specification) + reportskippedtable(f,fontdata,"colr",specification.glyphs) +end +function readers.cpal(f,fontdata,specification) + reportskippedtable(f,fontdata,"cpal",specification.glyphs) +end +function readers.svg(f,fontdata,specification) + reportskippedtable(f,fontdata,"svg",specification.glyphs) +end +function readers.sbix(f,fontdata,specification) + reportskippedtable(f,fontdata,"sbix",specification.glyphs) +end +function readers.cbdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"cbdt",specification.glyphs) +end +function readers.cblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"cblc",specification.glyphs) +end +function readers.ebdt(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebdt",specification.glyphs) +end +function readers.ebsc(f,fontdata,specification) + reportskippedtable(f,fontdata,"ebsc",specification.glyphs) +end +function readers.eblc(f,fontdata,specification) + reportskippedtable(f,fontdata,"eblc",specification.glyphs) +end +function readers.kern(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + local kerns={} + local glyphs=fontdata.glyphs + for i=1,nofpairs do + local left=readushort(f) + local right=readushort(f) + local kern=readfword(f) + local glyph=glyphs[left] + local kerns=glyph.kerns + if kerns then + kerns[right]=kern + else + glyph.kerns={ [right]=kern } + end + end + elseif format==2 then + report("todo: kern classes") + else + report("todo: kerns") + end + end + end +end +function readers.gdef(f,fontdata,specification) + reportskippedtable(f,fontdata,"gdef",specification.details) +end +function readers.gsub(f,fontdata,specification) + reportskippedtable(f,fontdata,"gsub",specification.details) +end +function readers.gpos(f,fontdata,specification) + reportskippedtable(f,fontdata,"gpos",specification.details) +end +function readers.math(f,fontdata,specification) + reportskippedtable(f,fontdata,"math",specification.details) +end +local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) + local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata + local names=fontdata.names + local info=nil + if names then + local metrics=fontdata.windowsmetrics or {} + local postscript=fontdata.postscript or {} + local fontheader=fontdata.fontheader or {} + local cffinfo=fontdata.cffinfo or {} + local verticalheader=fontdata.verticalheader or {} + local filename=fontdata.filename + local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) + local fontname=getname(fontdata,"postscriptname") + local fullname=getname(fontdata,"fullname") + local family=getname(fontdata,"family") + local subfamily=getname(fontdata,"subfamily") + local familyname=getname(fontdata,"typographicfamily") + local subfamilyname=getname(fontdata,"typographicsubfamily") + local compatiblename=getname(fontdata,"compatiblefullname") + if rawfamilynames then + else + if not familyname then familyname=family end + if not subfamilyname then subfamilyname=subfamily end + end + if platformnames then + platformnames=fontdata.platformnames + end + if instancenames then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata and variabledata.instances + if instances then + instancenames={} + for i=1,#instances do + instancenames[i]=lower(stripstring(instances[i].subfamily)) + end + else + instancenames=nil + end + else + instancenames=nil + end + end + info={ + subfontindex=fontdata.subfontindex or sub or 0, + version=getname(fontdata,"version"), + fontname=fontname, + fullname=fullname, + family=family, + subfamily=subfamily, + familyname=familyname, + subfamilyname=subfamilyname, + compatiblename=compatiblename, + weight=weight and lower(weight), + width=width and lower(width), + pfmweight=metrics.weightclass or 400, + pfmwidth=metrics.widthclass or 5, + panosewidth=metrics.panosewidth, + panoseweight=metrics.panoseweight, + italicangle=postscript.italicangle or 0, + units=fontheader.units or 0, + designsize=fontdata.designsize, + minsize=fontdata.minsize, + maxsize=fontdata.maxsize, + boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil, + monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", + averagewidth=metrics.averagewidth, + xheight=metrics.xheight, + capheight=metrics.capheight or fontdata.maxy, + ascender=metrics.typoascender, + descender=metrics.typodescender, + platformnames=platformnames or nil, + instancenames=instancenames or nil, + tableoffsets=fontdata.tableoffsets, + defaultvheight=(verticalheader.ascender or 0)-(verticalheader.descender or 0) + } + if metricstoo then + local keys={ + "version", + "ascender","descender","linegap", + "maxadvancewidth","maxadvanceheight","maxextent", + "minbottomsidebearing","mintopsidebearing", + } + local h=fontdata.horizontalheader or {} + local v=fontdata.verticalheader or {} + if h then + local th={} + local tv={} + for i=1,#keys do + local key=keys[i] + th[key]=h[key] or 0 + tv[key]=v[key] or 0 + end + info.horizontalmetrics=th + info.verticalmetrics=tv + end + end + elseif n then + info={ + filename=fontdata.filename, + comment="there is no info for subfont "..n, + } + else + info={ + filename=fontdata.filename, + comment="there is no info", + } + end + return info +end +local function loadtables(f,specification,offset) + if offset then + setposition(f,offset) + end + local tables={} + local basename=file.basename(specification.filename) + local filesize=specification.filesize + local filetime=specification.filetime + local fontdata={ + filename=basename, + filesize=filesize, + filetime=filetime, + version=readstring(f,4), + noftables=readushort(f), + searchrange=readushort(f), + entryselector=readushort(f), + rangeshift=readushort(f), + tables=tables, + foundtables=false, + } + for i=1,fontdata.noftables do + local tag=lower(stripstring(readstring(f,4))) + local checksum=readushort(f)*0x10000+readushort(f) + local offset=readulong(f) + local length=readulong(f) + if offset+length>filesize then + report("bad %a table in file %a",tag,basename) + end + tables[tag]={ + checksum=checksum, + offset=offset, + length=length, + } + end + fontdata.foundtables=sortedkeys(tables) + if tables.cff or tables.cff2 then + fontdata.format="opentype" + else + fontdata.format="truetype" + end + return fontdata,tables +end +local function prepareglyps(fontdata) + local glyphs=setmetatableindex(function(t,k) + local v={ + index=k, + } + t[k]=v + return v + end) + fontdata.glyphs=glyphs + fontdata.mapping={} +end +local function readtable(tag,f,fontdata,specification,...) + local reader=readers[tag] + if reader then + reader(f,fontdata,specification,...) + end +end +local function readdata(f,offset,specification) + local fontdata,tables=loadtables(f,specification,offset) + if specification.glyphs then + prepareglyps(fontdata) + end + fontdata.temporary={} + readtable("name",f,fontdata,specification) + local askedname=specification.askedname + if askedname then + local fullname=getname(fontdata,"fullname") or "" + local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") + local foundname=gsub(fullname,"[^a-zA-Z0-9]","") + if lower(cleanname)~=lower(foundname) then + return + end + end + readtable("stat",f,fontdata,specification) + readtable("avar",f,fontdata,specification) + readtable("fvar",f,fontdata,specification) + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata.instances + local axis=variabledata.axis + if axis and (not instances or #instances==0) then + instances={} + variabledata.instances=instances + local function add(n,subfamily,value) + local values={} + for i=1,#axis do + local a=axis[i] + values[i]={ + axis=a.tag, + value=i==n and value or a.default, + } + end + instances[#instances+1]={ + subfamily=subfamily, + values=values, + } + end + for i=1,#axis do + local a=axis[i] + local tag=a.tag + add(i,"default"..tag,a.default) + add(i,"minimum"..tag,a.minimum) + add(i,"maximum"..tag,a.maximum) + end + end + end + if not specification.factors then + local instance=specification.instance + if type(instance)=="string" then + local factors=helpers.getfactors(fontdata,instance) + if factors then + specification.factors=factors + fontdata.factors=factors + fontdata.instance=instance + report("user instance: %s, factors: % t",instance,factors) + else + report("user instance: %s, bad factors",instance) + end + end + end + if not fontdata.factors then + if fontdata.variabledata then + local factors=helpers.getfactors(fontdata,true) + if factors then + specification.factors=factors + fontdata.factors=factors + end + else + end + end + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + readtable("mvar",f,fontdata,specification) + readtable("hvar",f,fontdata,specification) + readtable("vvar",f,fontdata,specification) + readtable("gdef",f,fontdata,specification) + readtable("cff",f,fontdata,specification) + readtable("cff2",f,fontdata,specification) + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) + readtable("glyf",f,fontdata,specification) + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + readtable("svg",f,fontdata,specification) + readtable("sbix",f,fontdata,specification) + readtable("cbdt",f,fontdata,specification) + readtable("cblc",f,fontdata,specification) + readtable("ebdt",f,fontdata,specification) + readtable("eblc",f,fontdata,specification) + readtable("kern",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + readtable("math",f,fontdata,specification) + fontdata.locations=nil + fontdata.cidmaps=nil + fontdata.dictionaries=nil + if specification.tableoffsets then + fontdata.tableoffsets=tables + setmetatableindex(tables,{ + version=fontdata.version, + noftables=fontdata.noftables, + searchrange=fontdata.searchrange, + entryselector=fontdata.entryselector, + rangeshift=fontdata.rangeshift, + }) + end + return fontdata +end +local function loadfontdata(specification) + local filename=specification.filename + local fileattr=lfs.attributes(filename) + local filesize=fileattr and fileattr.size or 0 + local filetime=fileattr and fileattr.modification or 0 + local f=openfile(filename,true) + if not f then + report("unable to open %a",filename) + elseif filesize==0 then + report("empty file %a",filename) + closefile(f) + else + specification.filesize=filesize + specification.filetime=filetime + local version=readstring(f,4) + local fontdata=nil + if version=="OTTO" or version=="true" or version=="\0\1\0\0" then + fontdata=readdata(f,0,specification) + elseif version=="ttcf" then + local subfont=tonumber(specification.subfont) + local ttcversion=readulong(f) + local nofsubfonts=readulong(f) + local offsets=readcardinaltable(f,nofsubfonts,ulong) + if subfont then + if subfont>=1 and subfont<=nofsubfonts then + fontdata=readdata(f,offsets[subfont],specification) + else + report("no subfont %a in file %a",subfont,filename) + end + else + subfont=specification.subfont + if type(subfont)=="string" and subfont~="" then + specification.askedname=subfont + for i=1,nofsubfonts do + fontdata=readdata(f,offsets[i],specification) + if fontdata then + fontdata.subfontindex=i + report("subfont named %a has index %a",subfont,i) + break + end + end + if not fontdata then + report("no subfont named %a",subfont) + end + else + local subfonts={} + fontdata={ + filename=filename, + filesize=filesize, + filetime=filetime, + version=version, + subfonts=subfonts, + ttcversion=ttcversion, + nofsubfonts=nofsubfonts, + } + for i=1,nofsubfonts do + subfonts[i]=readdata(f,offsets[i],specification) + end + end + end + else + report("unknown version %a in file %a",version,filename) + end + closefile(f) + return fontdata or {} + end +end +local function loadfont(specification,n,instance) + if type(specification)=="string" then + specification={ + filename=specification, + info=true, + details=true, + glyphs=true, + shapes=true, + kerns=true, + variable=true, + globalkerns=true, + lookups=true, + subfont=n or true, + tounicode=false, + instance=instance + } + end + if specification.shapes or specification.lookups or specification.kerns then + specification.glyphs=true + end + if specification.glyphs then + specification.details=true + end + if specification.details then + specification.info=true + end + if specification.platformnames then + specification.platformnames=true + end + if specification.instance or instance then + specification.variable=true + specification.instance=specification.instance or instance + end + local function message(str) + report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) + end + local ok,result=xpcall(loadfontdata,message,specification) + if ok then + return result + end +end +function readers.loadshapes(filename,n,instance,streams) + local fontdata=loadfont { + filename=filename, + shapes=true, + streams=streams, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + for k,v in next,fontdata.glyphs do + v.class=nil + v.index=nil + v.math=nil + end + local names=fontdata.names + if names then + for k,v in next,names do + names[k]=fullstrip(v.content) + end + end + end + return fontdata and { + filename=filename, + format=fontdata.format, + glyphs=fontdata.glyphs, + units=fontdata.fontheader.units, + cffinfo=fontdata.cffinfo, + fontheader=fontdata.fontheader, + horizontalheader=fontdata.horizontalheader, + verticalheader=fontdata.verticalheader, + maximumprofile=fontdata.maximumprofile, + names=fontdata.names, + postscript=fontdata.postscript, + } or { + filename=filename, + format="unknown", + glyphs={}, + units=0, + } +end +function readers.loadfont(filename,n,instance) + local fontdata=loadfont { + filename=filename, + glyphs=true, + shapes=false, + lookups=true, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + return { + tableversion=tableversion, + creator="context mkiv", + size=fontdata.filesize, + time=fontdata.filetime, + glyphs=fontdata.glyphs, + descriptions=fontdata.descriptions, + format=fontdata.format, + goodies={}, + metadata=getinfo(fontdata,n,false,false,true,true), + properties={ + hasitalics=fontdata.hasitalics or false, + maxcolorclass=fontdata.maxcolorclass, + hascolor=fontdata.hascolor or false, + instance=fontdata.instance, + factors=fontdata.factors, + nofsubfonts=fontdata.subfonts and #fontdata.subfonts or nil, + }, + resources={ + filename=filename, + private=privateoffset, + duplicates=fontdata.duplicates or {}, + features=fontdata.features or {}, + sublookups=fontdata.sublookups or {}, + marks=fontdata.marks or {}, + markclasses=fontdata.markclasses or {}, + marksets=fontdata.marksets or {}, + sequences=fontdata.sequences or {}, + variants=fontdata.variants, + version=getname(fontdata,"version"), + cidinfo=fontdata.cidinfo, + mathconstants=fontdata.mathconstants, + colorpalettes=fontdata.colorpalettes, + svgshapes=fontdata.svgshapes, + pngshapes=fontdata.pngshapes, + variabledata=fontdata.variabledata, + foundtables=fontdata.foundtables, + }, + } + end +end +function readers.getinfo(filename,specification) + local subfont=nil + local platformnames=false + local rawfamilynames=false + local instancenames=true + local tableoffsets=false + if type(specification)=="table" then + subfont=tonumber(specification.subfont) + platformnames=specification.platformnames + rawfamilynames=specification.rawfamilynames + tableoffsets=specification.tableoffsets + else + subfont=tonumber(specification) + end + local fontdata=loadfont { + filename=filename, + details=true, + platformnames=platformnames, + instancenames=true, + tableoffsets=tableoffsets, + } + if fontdata then + local subfonts=fontdata.subfonts + if not subfonts then + return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) + elseif not subfont then + local info={} + for i=1,#subfonts do + info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) + end + return info + elseif subfont>=1 and subfont<=#subfonts then + return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) + else + return { + filename=filename, + comment="there is no subfont "..subfont.." in this file" + } + end + else + return { + filename=filename, + comment="the file cannot be opened for reading", + } + end +end +function readers.rehash(fontdata,hashmethod) + report("the %a helper is not yet implemented","rehash") +end +function readers.checkhash(fontdata) + report("the %a helper is not yet implemented","checkhash") +end +function readers.pack(fontdata,hashmethod) + report("the %a helper is not yet implemented","pack") +end +function readers.unpack(fontdata) + report("the %a helper is not yet implemented","unpack") +end +function readers.expand(fontdata) + report("the %a helper is not yet implemented","unpack") +end +function readers.compact(fontdata) + report("the %a helper is not yet implemented","compact") +end +local extenders={} +function readers.registerextender(extender) + extenders[#extenders+1]=extender +end +function readers.extend(fontdata) + for i=1,#extenders do + local extender=extenders[i] + local name=extender.name or "unknown" + local action=extender.action + if action then + action(fontdata) + end + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] --- + +if not modules then modules={} end modules ['font-oti']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lower=string.lower +local fonts=fonts +local constructors=fonts.constructors +local otf=constructors.handlers.otf +local otffeatures=constructors.features.otf +local registerotffeature=otffeatures.register +local otftables=otf.tables or {} +otf.tables=otftables +local allocate=utilities.storage.allocate +registerotffeature { + name="features", + description="initialization of feature handler", + default=true, +} +local function setmode(tfmdata,value) + if value then + tfmdata.properties.mode=lower(value) + end +end +otf.modeinitializer=setmode +local function setlanguage(tfmdata,value) + if value then + local cleanvalue=lower(value) + local languages=otftables and otftables.languages + local properties=tfmdata.properties + if not languages then + properties.language=cleanvalue + elseif languages[value] then + properties.language=cleanvalue + else + properties.language="dflt" + end + end +end +local function setscript(tfmdata,value) + if value then + local cleanvalue=lower(value) + local scripts=otftables and otftables.scripts + local properties=tfmdata.properties + if not scripts then + properties.script=cleanvalue + elseif scripts[value] then + properties.script=cleanvalue + else + properties.script="dflt" + end + end +end +registerotffeature { + name="mode", + description="mode", + initializers={ + base=setmode, + node=setmode, + plug=setmode, + } +} +registerotffeature { + name="language", + description="language", + initializers={ + base=setlanguage, + node=setlanguage, + plug=setlanguage, + } +} +registerotffeature { + name="script", + description="script", + initializers={ + base=setscript, + node=setscript, + plug=setscript, + } +} +otftables.featuretypes=allocate { + gpos_single="position", + gpos_pair="position", + gpos_cursive="position", + gpos_mark2base="position", + gpos_mark2ligature="position", + gpos_mark2mark="position", + gpos_context="position", + gpos_contextchain="position", + gsub_single="substitution", + gsub_multiple="substitution", + gsub_alternate="substitution", + gsub_ligature="substitution", + gsub_context="substitution", + gsub_contextchain="substitution", + gsub_reversecontextchain="substitution", + gsub_reversesub="substitution", +} +function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) + if featuretype=="position" then + local default=scripts.dflt + if default then + if autoscript=="position" or autoscript==true then + return default + else + report_otf("script feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=scripts.dflt + if default then + if autoscript=="substitution" or autoscript==true then + return default + end + end + end +end +function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) + if featuretype=="position" then + local default=languages.dflt + if default then + if autolanguage=="position" or autolanguage==true then + return default + else + report_otf("language feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=languages.dflt + if default then + if autolanguage=="substitution" or autolanguage==true then + return default + end + end + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott” 673ed11e1d159997f535bfec5fa73808] --- + +if not modules then modules={} end modules ["font-ott"]={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset +local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find +local sequenced=table.sequenced +local is_boolean=string.is_boolean +local setmetatableindex=table.setmetatableindex +local setmetatablenewindex=table.setmetatablenewindex +local allocate=utilities.storage.allocate +local fonts=fonts +local otf=fonts.handlers.otf +local otffeatures=otf.features +local tables=otf.tables or {} +otf.tables=tables +local statistics=otf.statistics or {} +otf.statistics=statistics +local scripts=allocate { + ["adlm"]="adlam", + ["aghb"]="caucasian albanian", + ["ahom"]="ahom", + ["arab"]="arabic", + ["armi"]="imperial aramaic", + ["armn"]="armenian", + ["avst"]="avestan", + ["bali"]="balinese", + ["bamu"]="bamum", + ["bass"]="bassa vah", + ["batk"]="batak", + ["beng"]="bengali", + ["bhks"]="bhaiksuki", + ["bng2"]="bengali variant 2", + ["bopo"]="bopomofo", + ["brah"]="brahmi", + ["brai"]="braille", + ["bugi"]="buginese", + ["buhd"]="buhid", + ["byzm"]="byzantine music", + ["cakm"]="chakma", + ["cans"]="canadian syllabics", + ["cari"]="carian", + ["cham"]="cham", + ["cher"]="cherokee", + ["copt"]="coptic", + ["cprt"]="cypriot syllabary", + ["cyrl"]="cyrillic", + ["dev2"]="devanagari variant 2", + ["deva"]="devanagari", + ["dogr"]="dogra", + ["dsrt"]="deseret", + ["dupl"]="duployan", + ["egyp"]="egyptian heiroglyphs", + ["elba"]="elbasan", + ["ethi"]="ethiopic", + ["geor"]="georgian", + ["gjr2"]="gujarati variant 2", + ["glag"]="glagolitic", + ["gong"]="gunjala gondi", + ["gonm"]="masaram gondi", + ["goth"]="gothic", + ["gran"]="grantha", + ["grek"]="greek", + ["gujr"]="gujarati", + ["gur2"]="gurmukhi variant 2", + ["guru"]="gurmukhi", + ["hang"]="hangul", + ["hani"]="cjk ideographic", + ["hano"]="hanunoo", + ["hatr"]="hatran", + ["hebr"]="hebrew", + ["hluw"]="anatolian hieroglyphs", + ["hmng"]="pahawh hmong", + ["hung"]="old hungarian", + ["ital"]="old italic", + ["jamo"]="hangul jamo", + ["java"]="javanese", + ["kali"]="kayah li", + ["kana"]="hiragana and katakana", + ["khar"]="kharosthi", + ["khmr"]="khmer", + ["khoj"]="khojki", + ["knd2"]="kannada variant 2", + ["knda"]="kannada", + ["kthi"]="kaithi", + ["lana"]="tai tham", + ["lao" ]="lao", + ["latn"]="latin", + ["lepc"]="lepcha", + ["limb"]="limbu", + ["lina"]="linear a", + ["linb"]="linear b", + ["lisu"]="lisu", + ["lyci"]="lycian", + ["lydi"]="lydian", + ["mahj"]="mahajani", + ["maka"]="makasar", + ["mand"]="mandaic and mandaean", + ["mani"]="manichaean", + ["marc"]="marchen", + ["math"]="mathematical alphanumeric symbols", + ["medf"]="medefaidrin", + ["mend"]="mende kikakui", + ["merc"]="meroitic cursive", + ["mero"]="meroitic hieroglyphs", + ["mlm2"]="malayalam variant 2", + ["mlym"]="malayalam", + ["modi"]="modi", + ["mong"]="mongolian", + ["mroo"]="mro", + ["mtei"]="meitei Mayek", + ["mult"]="multani", + ["musc"]="musical symbols", + ["mym2"]="myanmar variant 2", + ["mymr"]="myanmar", + ["narb"]="old north arabian", + ["nbat"]="nabataean", + ["newa"]="newa", + ["nko" ]='n"ko', + ["nshu"]="nüshu", + ["ogam"]="ogham", + ["olck"]="ol chiki", + ["orkh"]="old turkic and orkhon runic", + ["ory2"]="odia variant 2", + ["orya"]="oriya", + ["osge"]="osage", + ["osma"]="osmanya", + ["palm"]="palmyrene", + ["pauc"]="pau cin hau", + ["perm"]="old permic", + ["phag"]="phags-pa", + ["phli"]="inscriptional pahlavi", + ["phlp"]="psalter pahlavi", + ["phnx"]="phoenician", + ["plrd"]="miao", + ["prti"]="inscriptional parthian", + ["rjng"]="rejang", + ["rohg"]="hanifi rohingya", + ["runr"]="runic", + ["samr"]="samaritan", + ["sarb"]="old south arabian", + ["saur"]="saurashtra", + ["sgnw"]="sign writing", + ["shaw"]="shavian", + ["shrd"]="sharada", + ["sidd"]="siddham", + ["sind"]="khudawadi", + ["sinh"]="sinhala", + ["sogd"]="sogdian", + ["sogo"]="old sogdian", + ["sora"]="sora sompeng", + ["soyo"]="soyombo", + ["sund"]="sundanese", + ["sylo"]="syloti nagri", + ["syrc"]="syriac", + ["tagb"]="tagbanwa", + ["takr"]="takri", + ["tale"]="tai le", + ["talu"]="tai lu", + ["taml"]="tamil", + ["tang"]="tangut", + ["tavt"]="tai viet", + ["tel2"]="telugu variant 2", + ["telu"]="telugu", + ["tfng"]="tifinagh", + ["tglg"]="tagalog", + ["thaa"]="thaana", + ["thai"]="thai", + ["tibt"]="tibetan", + ["tirh"]="tirhuta", + ["tml2"]="tamil variant 2", + ["ugar"]="ugaritic cuneiform", + ["vai" ]="vai", + ["wara"]="warang citi", + ["xpeo"]="old persian cuneiform", + ["xsux"]="sumero-akkadian cuneiform", + ["yi" ]="yi", + ["zanb"]="zanabazar square", +} +local languages=allocate { + ["aba" ]="abaza", + ["abk" ]="abkhazian", + ["ach" ]="acholi", + ["acr" ]="achi", + ["ady" ]="adyghe", + ["afk" ]="afrikaans", + ["afr" ]="afar", + ["agw" ]="agaw", + ["aio" ]="aiton", + ["aka" ]="akan", + ["als" ]="alsatian", + ["alt" ]="altai", + ["amh" ]="amharic", + ["ang" ]="anglo-saxon", + ["apph"]="phonetic transcription—americanist conventions", + ["ara" ]="arabic", + ["arg" ]="aragonese", + ["ari" ]="aari", + ["ark" ]="rakhine", + ["asm" ]="assamese", + ["ast" ]="asturian", + ["ath" ]="athapaskan", + ["avr" ]="avar", + ["awa" ]="awadhi", + ["aym" ]="aymara", + ["azb" ]="torki", + ["aze" ]="azerbaijani", + ["bad" ]="badaga", + ["bad0"]="banda", + ["bag" ]="baghelkhandi", + ["bal" ]="balkar", + ["ban" ]="balinese", + ["bar" ]="bavarian", + ["bau" ]="baulé", + ["bbc" ]="batak toba", + ["bbr" ]="berber", + ["bch" ]="bench", + ["bcr" ]="bible cree", + ["bdy" ]="bandjalang", + ["bel" ]="belarussian", + ["bem" ]="bemba", + ["ben" ]="bengali", + ["bgc" ]="haryanvi", + ["bgq" ]="bagri", + ["bgr" ]="bulgarian", + ["bhi" ]="bhili", + ["bho" ]="bhojpuri", + ["bik" ]="bikol", + ["bil" ]="bilen", + ["bis" ]="bislama", + ["bjj" ]="kanauji", + ["bkf" ]="blackfoot", + ["bli" ]="baluchi", + ["blk" ]="pa'o karen", + ["bln" ]="balante", + ["blt" ]="balti", + ["bmb" ]="bambara (bamanankan)", + ["bml" ]="bamileke", + ["bos" ]="bosnian", + ["bpy" ]="bishnupriya manipuri", + ["bre" ]="breton", + ["brh" ]="brahui", + ["bri" ]="braj bhasha", + ["brm" ]="burmese", + ["brx" ]="bodo", + ["bsh" ]="bashkir", + ["bsk" ]="burushaski", + ["bti" ]="beti", + ["bts" ]="batak simalungun", + ["bug" ]="bugis", + ["byv" ]="medumba", + ["cak" ]="kaqchikel", + ["cat" ]="catalan", + ["cbk" ]="zamboanga chavacano", + ["cchn"]="chinantec", + ["ceb" ]="cebuano", + ["cgg" ]="chiga", + ["cha" ]="chamorro", + ["che" ]="chechen", + ["chg" ]="chaha gurage", + ["chh" ]="chattisgarhi", + ["chi" ]="chichewa (chewa, nyanja)", + ["chk" ]="chukchi", + ["chk0"]="chuukese", + ["cho" ]="choctaw", + ["chp" ]="chipewyan", + ["chr" ]="cherokee", + ["chu" ]="chuvash", + ["chy" ]="cheyenne", + ["cja" ]="western cham", + ["cjm" ]="eastern cham", + ["cmr" ]="comorian", + ["cop" ]="coptic", + ["cor" ]="cornish", + ["cos" ]="corsican", + ["cpp" ]="creoles", + ["cre" ]="cree", + ["crr" ]="carrier", + ["crt" ]="crimean tatar", + ["csb" ]="kashubian", + ["csl" ]="church slavonic", + ["csy" ]="czech", + ["ctg" ]="chittagonian", + ["cuk" ]="san blas kuna", + ["dan" ]="danish", + ["dar" ]="dargwa", + ["dax" ]="dayi", + ["dcr" ]="woods cree", + ["deu" ]="german", + ["dgo" ]="dogri", + ["dgr" ]="dogri", + ["dhg" ]="dhangu", + ["dhv" ]="divehi (dhivehi, maldivian)", + ["diq" ]="dimli", + ["div" ]="divehi (dhivehi, maldivian)", + ["djr" ]="zarma", + ["djr0"]="djambarrpuyngu", + ["dng" ]="dangme", + ["dnj" ]="dan", + ["dnk" ]="dinka", + ["dri" ]="dari", + ["duj" ]="dhuwal", + ["dun" ]="dungan", + ["dzn" ]="dzongkha", + ["ebi" ]="ebira", + ["ecr" ]="eastern cree", + ["edo" ]="edo", + ["efi" ]="efik", + ["ell" ]="greek", + ["emk" ]="eastern maninkakan", + ["eng" ]="english", + ["erz" ]="erzya", + ["esp" ]="spanish", + ["esu" ]="central yupik", + ["eti" ]="estonian", + ["euq" ]="basque", + ["evk" ]="evenki", + ["evn" ]="even", + ["ewe" ]="ewe", + ["fan" ]="french antillean", + ["fan0"]=" fang", + ["far" ]="persian", + ["fat" ]="fanti", + ["fin" ]="finnish", + ["fji" ]="fijian", + ["fle" ]="dutch (flemish)", + ["fmp" ]="fe’fe’", + ["fne" ]="forest nenets", + ["fon" ]="fon", + ["fos" ]="faroese", + ["fra" ]="french", + ["frc" ]="cajun french", + ["fri" ]="frisian", + ["frl" ]="friulian", + ["frp" ]="arpitan", + ["fta" ]="futa", + ["ful" ]="fulah", + ["fuv" ]="nigerian fulfulde", + ["gad" ]="ga", + ["gae" ]="scottish gaelic (gaelic)", + ["gag" ]="gagauz", + ["gal" ]="galician", + ["gar" ]="garshuni", + ["gaw" ]="garhwali", + ["gez" ]="ge'ez", + ["gih" ]="githabul", + ["gil" ]="gilyak", + ["gil0"]="kiribati (gilbertese)", + ["gkp" ]="kpelle (guinea)", + ["glk" ]="gilaki", + ["gmz" ]="gumuz", + ["gnn" ]="gumatj", + ["gog" ]="gogo", + ["gon" ]="gondi", + ["grn" ]="greenlandic", + ["gro" ]="garo", + ["gua" ]="guarani", + ["guc" ]="wayuu", + ["guf" ]="gupapuyngu", + ["guj" ]="gujarati", + ["guz" ]="gusii", + ["hai" ]="haitian (haitian creole)", + ["hal" ]="halam", + ["har" ]="harauti", + ["hau" ]="hausa", + ["haw" ]="hawaiian", + ["hay" ]="haya", + ["haz" ]="hazaragi", + ["hbn" ]="hammer-banna", + ["her" ]="herero", + ["hil" ]="hiligaynon", + ["hin" ]="hindi", + ["hma" ]="high mari", + ["hmn" ]="hmong", + ["hmo" ]="hiri motu", + ["hnd" ]="hindko", + ["ho" ]="ho", + ["hri" ]="harari", + ["hrv" ]="croatian", + ["hun" ]="hungarian", + ["hye" ]="armenian", + ["hye0"]="armenian east", + ["iba" ]="iban", + ["ibb" ]="ibibio", + ["ibo" ]="igbo", + ["ido" ]="ido", + ["ijo" ]="ijo languages", + ["ile" ]="interlingue", + ["ilo" ]="ilokano", + ["ina" ]="interlingua", + ["ind" ]="indonesian", + ["ing" ]="ingush", + ["inu" ]="inuktitut", + ["ipk" ]="inupiat", + ["ipph"]="phonetic transcription—ipa conventions", + ["iri" ]="irish", + ["irt" ]="irish traditional", + ["isl" ]="icelandic", + ["ism" ]="inari sami", + ["ita" ]="italian", + ["iwr" ]="hebrew", + ["jam" ]="jamaican creole", + ["jan" ]="japanese", + ["jav" ]="javanese", + ["jbo" ]="lojban", + ["jct" ]="krymchak", + ["jii" ]="yiddish", + ["jud" ]="ladino", + ["jul" ]="jula", + ["kab" ]="kabardian", + ["kab0"]="kabyle", + ["kac" ]="kachchi", + ["kal" ]="kalenjin", + ["kan" ]="kannada", + ["kar" ]="karachay", + ["kat" ]="georgian", + ["kaz" ]="kazakh", + ["kde" ]="makonde", + ["kea" ]="kabuverdianu (crioulo)", + ["keb" ]="kebena", + ["kek" ]="kekchi", + ["kge" ]="khutsuri georgian", + ["kha" ]="khakass", + ["khk" ]="khanty-kazim", + ["khm" ]="khmer", + ["khs" ]="khanty-shurishkar", + ["kht" ]="khamti shan", + ["khv" ]="khanty-vakhi", + ["khw" ]="khowar", + ["kik" ]="kikuyu (gikuyu)", + ["kir" ]="kirghiz (kyrgyz)", + ["kis" ]="kisii", + ["kiu" ]="kirmanjki", + ["kjd" ]="southern kiwai", + ["kjp" ]="eastern pwo karen", + ["kjz" ]="bumthangkha", + ["kkn" ]="kokni", + ["klm" ]="kalmyk", + ["kmb" ]="kamba", + ["kmn" ]="kumaoni", + ["kmo" ]="komo", + ["kms" ]="komso", + ["kmz" ]="khorasani turkic", + ["knr" ]="kanuri", + ["kod" ]="kodagu", + ["koh" ]="korean old hangul", + ["kok" ]="konkani", + ["kom" ]="komi", + ["kon" ]="kikongo", + ["kon0"]="kongo", + ["kop" ]="komi-permyak", + ["kor" ]="korean", + ["kos" ]="kosraean", + ["koz" ]="komi-zyrian", + ["kpl" ]="kpelle", + ["kri" ]="krio", + ["krk" ]="karakalpak", + ["krl" ]="karelian", + ["krm" ]="karaim", + ["krn" ]="karen", + ["krt" ]="koorete", + ["ksh" ]="kashmiri", + ["ksh0"]="ripuarian", + ["ksi" ]="khasi", + ["ksm" ]="kildin sami", + ["ksw" ]="s’gaw karen", + ["kua" ]="kuanyama", + ["kui" ]="kui", + ["kul" ]="kulvi", + ["kum" ]="kumyk", + ["kur" ]="kurdish", + ["kuu" ]="kurukh", + ["kuy" ]="kuy", + ["kyk" ]="koryak", + ["kyu" ]="western kayah", + ["lad" ]="ladin", + ["lah" ]="lahuli", + ["lak" ]="lak", + ["lam" ]="lambani", + ["lao" ]="lao", + ["lat" ]="latin", + ["laz" ]="laz", + ["lcr" ]="l-cree", + ["ldk" ]="ladakhi", + ["lez" ]="lezgi", + ["lij" ]="ligurian", + ["lim" ]="limburgish", + ["lin" ]="lingala", + ["lis" ]="lisu", + ["ljp" ]="lampung", + ["lki" ]="laki", + ["lma" ]="low mari", + ["lmb" ]="limbu", + ["lmo" ]="lombard", + ["lmw" ]="lomwe", + ["lom" ]="loma", + ["lrc" ]="luri", + ["lsb" ]="lower sorbian", + ["lsm" ]="lule sami", + ["lth" ]="lithuanian", + ["ltz" ]="luxembourgish", + ["lua" ]="luba-lulua", + ["lub" ]="luba-katanga", + ["lug" ]="ganda", + ["luh" ]="luyia", + ["luo" ]="luo", + ["lvi" ]="latvian", + ["mad" ]="madura", + ["mag" ]="magahi", + ["mah" ]="marshallese", + ["maj" ]="majang", + ["mak" ]="makhuwa", + ["mal" ]="malayalam reformed", + ["mam" ]="mam", + ["man" ]="mansi", + ["map" ]="mapudungun", + ["mar" ]="marathi", + ["maw" ]="marwari", + ["mbn" ]="mbundu", + ["mbo" ]="mbo", + ["mch" ]="manchu", + ["mcr" ]="moose cree", + ["mde" ]="mende", + ["mdr" ]="mandar", + ["men" ]="me'en", + ["mer" ]="meru", + ["mfa" ]="pattani malay", + ["mfe" ]="morisyen", + ["min" ]="minangkabau", + ["miz" ]="mizo", + ["mkd" ]="macedonian", + ["mkr" ]="makasar", + ["mkw" ]="kituba", + ["mle" ]="male", + ["mlg" ]="malagasy", + ["mln" ]="malinke", + ["mlr" ]="malayalam reformed", + ["mly" ]="malay", + ["mnd" ]="mandinka", + ["mng" ]="mongolian", + ["mni" ]="manipuri", + ["mnk" ]="maninka", + ["mnx" ]="manx", + ["moh" ]="mohawk", + ["mok" ]="moksha", + ["mol" ]="moldavian", + ["mon" ]="mon", + ["mor" ]="moroccan", + ["mos" ]="mossi", + ["mri" ]="maori", + ["mth" ]="maithili", + ["mts" ]="maltese", + ["mun" ]="mundari", + ["mus" ]="muscogee", + ["mwl" ]="mirandese", + ["mww" ]="hmong daw", + ["myn" ]="mayan", + ["mzn" ]="mazanderani", + ["nag" ]="naga-assamese", + ["nah" ]="nahuatl", + ["nan" ]="nanai", + ["nap" ]="neapolitan", + ["nas" ]="naskapi", + ["nau" ]="nauruan", + ["nav" ]="navajo", + ["ncr" ]="n-cree", + ["ndb" ]="ndebele", + ["ndc" ]="ndau", + ["ndg" ]="ndonga", + ["nds" ]="low saxon", + ["nep" ]="nepali", + ["new" ]="newari", + ["nga" ]="ngbaka", + ["ngr" ]="nagari", + ["nhc" ]="norway house cree", + ["nis" ]="nisi", + ["niu" ]="niuean", + ["nkl" ]="nyankole", + ["nko" ]="n'ko", + ["nld" ]="dutch", + ["noe" ]="nimadi", + ["nog" ]="nogai", + ["nor" ]="norwegian", + ["nov" ]="novial", + ["nsm" ]="northern sami", + ["nso" ]="sotho, northern", + ["nta" ]="northern tai", + ["nto" ]="esperanto", + ["nym" ]="nyamwezi", + ["nyn" ]="norwegian nynorsk", + ["nza" ]="mbembe tigon", + ["oci" ]="occitan", + ["ocr" ]="oji-cree", + ["ojb" ]="ojibway", + ["ori" ]="odia", + ["oro" ]="oromo", + ["oss" ]="ossetian", + ["paa" ]="palestinian aramaic", + ["pag" ]="pangasinan", + ["pal" ]="pali", + ["pam" ]="pampangan", + ["pan" ]="punjabi", + ["pap" ]="palpa", + ["pap0"]="papiamentu", + ["pas" ]="pashto", + ["pau" ]="palauan", + ["pcc" ]="bouyei", + ["pcd" ]="picard", + ["pdc" ]="pennsylvania german", + ["pgr" ]="polytonic greek", + ["phk" ]="phake", + ["pih" ]="norfolk", + ["pil" ]="filipino", + ["plg" ]="palaung", + ["plk" ]="polish", + ["pms" ]="piemontese", + ["pnb" ]="western panjabi", + ["poh" ]="pocomchi", + ["pon" ]="pohnpeian", + ["pro" ]="provencal", + ["ptg" ]="portuguese", + ["pwo" ]="western pwo karen", + ["qin" ]="chin", + ["quc" ]="k’iche’", + ["quh" ]="quechua (bolivia)", + ["quz" ]="quechua", + ["qvi" ]="quechua (ecuador)", + ["qwh" ]="quechua (peru)", + ["raj" ]="rajasthani", + ["rar" ]="rarotongan", + ["rbu" ]="russian buriat", + ["rcr" ]="r-cree", + ["rej" ]="rejang", + ["ria" ]="riang", + ["rif" ]="tarifit", + ["rit" ]="ritarungo", + ["rkw" ]="arakwal", + ["rms" ]="romansh", + ["rmy" ]="vlax romani", + ["rom" ]="romanian", + ["roy" ]="romany", + ["rsy" ]="rusyn", + ["rtm" ]="rotuman", + ["rua" ]="kinyarwanda", + ["run" ]="rundi", + ["rup" ]="aromanian", + ["rus" ]="russian", + ["sad" ]="sadri", + ["san" ]="sanskrit", + ["sas" ]="sasak", + ["sat" ]="santali", + ["say" ]="sayisi", + ["scn" ]="sicilian", + ["sco" ]="scots", + ["scs" ]="north slavey", + ["sek" ]="sekota", + ["sel" ]="selkup", + ["sga" ]="old irish", + ["sgo" ]="sango", + ["sgs" ]="samogitian", + ["shi" ]="tachelhit", + ["shn" ]="shan", + ["sib" ]="sibe", + ["sid" ]="sidamo", + ["sig" ]="silte gurage", + ["sks" ]="skolt sami", + ["sky" ]="slovak", + ["sla" ]="slavey", + ["slv" ]="slovenian", + ["sml" ]="somali", + ["smo" ]="samoan", + ["sna" ]="sena", + ["sna0"]="shona", + ["snd" ]="sindhi", + ["snh" ]="sinhala (sinhalese)", + ["snk" ]="soninke", + ["sog" ]="sodo gurage", + ["sop" ]="songe", + ["sot" ]="sotho, southern", + ["sqi" ]="albanian", + ["srb" ]="serbian", + ["srd" ]="sardinian", + ["srk" ]="saraiki", + ["srr" ]="serer", + ["ssl" ]="south slavey", + ["ssm" ]="southern sami", + ["stq" ]="saterland frisian", + ["suk" ]="sukuma", + ["sun" ]="sundanese", + ["sur" ]="suri", + ["sva" ]="svan", + ["sve" ]="swedish", + ["swa" ]="swadaya aramaic", + ["swk" ]="swahili", + ["swz" ]="swati", + ["sxt" ]="sutu", + ["sxu" ]="upper saxon", + ["syl" ]="sylheti", + ["syr" ]="syriac", + ["syre"]="estrangela syriac", + ["syrj"]="western syriac", + ["syrn"]="eastern syriac", + ["szl" ]="silesian", + ["tab" ]="tabasaran", + ["taj" ]="tajiki", + ["tam" ]="tamil", + ["tat" ]="tatar", + ["tcr" ]="th-cree", + ["tdd" ]="dehong dai", + ["tel" ]="telugu", + ["tet" ]="tetum", + ["tgl" ]="tagalog", + ["tgn" ]="tongan", + ["tgr" ]="tigre", + ["tgy" ]="tigrinya", + ["tha" ]="thai", + ["tht" ]="tahitian", + ["tib" ]="tibetan", + ["tiv" ]="tiv", + ["tkm" ]="turkmen", + ["tmh" ]="tamashek", + ["tmn" ]="temne", + ["tna" ]="tswana", + ["tne" ]="tundra nenets", + ["tng" ]="tonga", + ["tod" ]="todo", + ["tod0"]="toma", + ["tpi" ]="tok pisin", + ["trk" ]="turkish", + ["tsg" ]="tsonga", + ["tsj" ]="tshangla", + ["tua" ]="turoyo aramaic", + ["tul" ]="tulu", + ["tum" ]="tulu", + ["tuv" ]="tuvin", + ["tvl" ]="tuvalu", + ["twi" ]="twi", + ["tyz" ]="tày", + ["tzm" ]="tamazight", + ["tzo" ]="tzotzil", + ["udm" ]="udmurt", + ["ukr" ]="ukrainian", + ["umb" ]="umbundu", + ["urd" ]="urdu", + ["usb" ]="upper sorbian", + ["uyg" ]="uyghur", + ["uzb" ]="uzbek", + ["vec" ]="venetian", + ["ven" ]="venda", + ["vit" ]="vietnamese", + ["vol" ]="volapük", + ["vro" ]="võro", + ["wa" ]="wa", + ["wag" ]="wagdi", + ["war" ]="waray-waray", + ["wcr" ]="west-cree", + ["wel" ]="welsh", + ["wlf" ]="wolof", + ["wln" ]="walloon", + ["wtm" ]="mewati", + ["xbd" ]="lü", + ["xhs" ]="xhosa", + ["xjb" ]="minjangbal", + ["xkf" ]="khengkha", + ["xog" ]="soga", + ["xpe" ]="kpelle (liberia)", + ["yak" ]="sakha", + ["yao" ]="yao", + ["yap" ]="yapese", + ["yba" ]="yoruba", + ["ycr" ]="y-cree", + ["yic" ]="yi classic", + ["yim" ]="yi modern", + ["zea" ]="zealandic", + ["zgh" ]="standard morrocan tamazigh", + ["zha" ]="zhuang", + ["zhh" ]="chinese, hong kong sar", + ["zhp" ]="chinese phonetic", + ["zhs" ]="chinese simplified", + ["zht" ]="chinese traditional", + ["znd" ]="zande", + ["zul" ]="zulu", + ["zza" ]="zazaki", +} +local features=allocate { + ["aalt"]="access all alternates", + ["abvf"]="above-base forms", + ["abvm"]="above-base mark positioning", + ["abvs"]="above-base substitutions", + ["afrc"]="alternative fractions", + ["akhn"]="akhands", + ["blwf"]="below-base forms", + ["blwm"]="below-base mark positioning", + ["blws"]="below-base substitutions", + ["c2pc"]="petite capitals from capitals", + ["c2sc"]="small capitals from capitals", + ["calt"]="contextual alternates", + ["case"]="case-sensitive forms", + ["ccmp"]="glyph composition/decomposition", + ["cfar"]="conjunct form after ro", + ["cjct"]="conjunct forms", + ["clig"]="contextual ligatures", + ["cpct"]="centered cjk punctuation", + ["cpsp"]="capital spacing", + ["cswh"]="contextual swash", + ["curs"]="cursive positioning", + ["dflt"]="default processing", + ["dist"]="distances", + ["dlig"]="discretionary ligatures", + ["dnom"]="denominators", + ["dtls"]="dotless forms", + ["expt"]="expert forms", + ["falt"]="final glyph alternates", + ["fin2"]="terminal forms #2", + ["fin3"]="terminal forms #3", + ["fina"]="terminal forms", + ["flac"]="flattened accents over capitals", + ["frac"]="fractions", + ["fwid"]="full width", + ["half"]="half forms", + ["haln"]="halant forms", + ["halt"]="alternate half width", + ["hist"]="historical forms", + ["hkna"]="horizontal kana alternates", + ["hlig"]="historical ligatures", + ["hngl"]="hangul", + ["hojo"]="hojo kanji forms", + ["hwid"]="half width", + ["init"]="initial forms", + ["isol"]="isolated forms", + ["ital"]="italics", + ["jalt"]="justification alternatives", + ["jp04"]="jis2004 forms", + ["jp78"]="jis78 forms", + ["jp83"]="jis83 forms", + ["jp90"]="jis90 forms", + ["kern"]="kerning", + ["lfbd"]="left bounds", + ["liga"]="standard ligatures", + ["ljmo"]="leading jamo forms", + ["lnum"]="lining figures", + ["locl"]="localized forms", + ["ltra"]="left-to-right alternates", + ["ltrm"]="left-to-right mirrored forms", + ["mark"]="mark positioning", + ["med2"]="medial forms #2", + ["medi"]="medial forms", + ["mgrk"]="mathematical greek", + ["mkmk"]="mark to mark positioning", + ["mset"]="mark positioning via substitution", + ["nalt"]="alternate annotation forms", + ["nlck"]="nlc kanji forms", + ["nukt"]="nukta forms", + ["numr"]="numerators", + ["onum"]="old style figures", + ["opbd"]="optical bounds", + ["ordn"]="ordinals", + ["ornm"]="ornaments", + ["palt"]="proportional alternate width", + ["pcap"]="petite capitals", + ["pkna"]="proportional kana", + ["pnum"]="proportional figures", + ["pref"]="pre-base forms", + ["pres"]="pre-base substitutions", + ["pstf"]="post-base forms", + ["psts"]="post-base substitutions", + ["pwid"]="proportional widths", + ["qwid"]="quarter widths", + ["rand"]="randomize", + ["rclt"]="required contextual alternates", + ["rkrf"]="rakar forms", + ["rlig"]="required ligatures", + ["rphf"]="reph form", + ["rtbd"]="right bounds", + ["rtla"]="right-to-left alternates", + ["rtlm"]="right to left mirrored forms", + ["rvrn"]="required variation alternates", + ["ruby"]="ruby notation forms", + ["salt"]="stylistic alternates", + ["sinf"]="scientific inferiors", + ["size"]="optical size", + ["smcp"]="small capitals", + ["smpl"]="simplified forms", + ["ssty"]="script style", + ["stch"]="stretching glyph decomposition", + ["subs"]="subscript", + ["sups"]="superscript", + ["swsh"]="swash", + ["titl"]="titling", + ["tjmo"]="trailing jamo forms", + ["tnam"]="traditional name forms", + ["tnum"]="tabular figures", + ["trad"]="traditional forms", + ["twid"]="third widths", + ["unic"]="unicase", + ["valt"]="alternate vertical metrics", + ["vatu"]="vattu variants", + ["vert"]="vertical writing", + ["vhal"]="alternate vertical half metrics", + ["vjmo"]="vowel jamo forms", + ["vkna"]="vertical kana alternates", + ["vkrn"]="vertical kerning", + ["vpal"]="proportional alternate vertical metrics", + ["vrtr"]="vertical alternates for rotation", + ["vrt2"]="vertical rotation", + ["zero"]="slashed zero", + ["trep"]="traditional tex replacements", + ["tlig"]="traditional tex ligatures", + ["ss.."]="stylistic set ..", + ["cv.."]="character variant ..", + ["js.."]="justification ..", + ["dv.."]="devanagari ..", + ["ml.."]="malayalam ..", +} +local baselines=allocate { + ["hang"]="hanging baseline", + ["icfb"]="ideographic character face bottom edge baseline", + ["icft"]="ideographic character face tope edige baseline", + ["ideo"]="ideographic em-box bottom edge baseline", + ["idtp"]="ideographic em-box top edge baseline", + ["math"]="mathematical centered baseline", + ["romn"]="roman baseline" +} +tables.scripts=scripts +tables.languages=languages +tables.features=features +tables.baselines=baselines +local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end) +local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end) +local report_checks=logs.reporter("fonts","checks") +if otffeatures.features then + for k,v in next,otffeatures.features do + features[k]=v + end + otffeatures.features=features +end +local function swapped(h) + local r={} + for k,v in next,h do + r[gsub(v,"[^a-z0-9]","")]=k + end + return r +end +local verbosescripts=allocate(swapped(scripts )) +local verboselanguages=allocate(swapped(languages)) +local verbosefeatures=allocate(swapped(features )) +local verbosebaselines=allocate(swapped(baselines)) +local function resolve(t,k) + if k then + k=gsub(lower(k),"[^a-z0-9]","") + local v=rawget(t,k) + if v then + return v + end + end +end +setmetatableindex(verbosescripts,resolve) +setmetatableindex(verboselanguages,resolve) +setmetatableindex(verbosefeatures,resolve) +setmetatableindex(verbosebaselines,resolve) +setmetatableindex(scripts,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptscripts then + report_checks("registering extra script %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +setmetatableindex(languages,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptlanguages then + report_checks("registering extra language %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +if setmetatablenewindex then + setmetatablenewindex(languages,"ignore") + setmetatablenewindex(scripts,"ignore") + setmetatablenewindex(baselines,"ignore") +end +local function resolve(t,k) + if k then + k=lower(k) + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + local v=rawget(t,k) + if v then + return v + end + local tag,dd=match(k,"(..)(%d+)") + if tag and dd then + local v=rawget(t,tag) + if v then + return v + else + local v=rawget(t,tag.."..") + if v then + return (gsub(v,"%.%.",tonumber(dd))) + end + end + end + end + return k +end +setmetatableindex(features,resolve) +local function assign(t,k,v) + if k and v then + v=lower(v) + rawset(t,k,v) + end +end +if setmetatablenewindex then + setmetatablenewindex(features,assign) +end +local checkers={ + rand=function(v) + return v==true and "random" or v + end +} +if not storage then + return +end +local usedfeatures=statistics.usedfeatures or {} +statistics.usedfeatures=usedfeatures +table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) +storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" ) +local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end +function otffeatures.normalize(features,wrap) + if features then + local h={} + for key,value in next,features do + local k=lower(key) + if k=="language" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" + elseif k=="script" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" + elseif k=="axis" then + h[k]=normalizedaxis(value) + else + local uk=usedfeatures[key] + local uv=uk[value] + if uv then + else + uv=tonumber(value) + if uv then + elseif type(value)=="string" then + local b=is_boolean(value) + if type(b)=="nil" then + if wrap and find(value,",") then + uv="{"..lower(value).."}" + else + uv=lower(value) + end + else + uv=b + end + elseif type(value)=="table" then + uv=sequenced(t,",") + else + uv=value + end + if not rawget(features,k) then + k=rawget(verbosefeatures,k) or k + end + local c=checkers[k] + if c then + uv=c(uv) or vc + end + uk[value]=uv + end + h[k]=uv + end + end + return h + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff” 802a10ad12ac32329f540881f940e3f2] --- + +if not modules then modules={} end modules ['font-cff']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber,rawget=next,type,tonumber,rawget +local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub +local concat,remove,unpack=table.concat,table.remove,table.unpack +local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max +local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct +local lpegmatch=lpeg.match +local formatters=string.formatters +local bytetable=string.bytetable +local idiv=number.idiv +local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local readstring=streamreader.readstring +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 +local readulong=streamreader.readcardinal4 +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local readbytetable=streamreader.readbytetable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + setposition=streamreader.setposition + getposition=streamreader.getposition + readbytetable=streamreader.readbytetable +end) +local setmetatableindex=table.setmetatableindex +local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) +local report=logs.reporter("otf reader","cff") +local parsedictionaries +local parsecharstring +local parsecharstrings +local resetcharstrings +local parseprivates +local startparsing +local stopparsing +local defaultstrings={ [0]= + ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", + "sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl","endash","dagger","daggerdbl", + "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", + "quotedblright","guillemotright","ellipsis","perthousand","questiondown", + "grave","acute","circumflex","tilde","macron","breve","dotaccent", + "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", + "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", + "dotlessi","lslash","oslash","oe","germandbls","onesuperior", + "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", + "onequarter","divide","brokenbar","degree","thorn","threequarters", + "twosuperior","registered","minus","eth","multiply","threesuperior", + "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", + "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", + "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", + "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", + "aacute","acircumflex","adieresis","agrave","aring","atilde", + "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", + "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", + "odieresis","ograve","otilde","scaron","uacute","ucircumflex", + "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", + "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", + "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", + "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", + "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", + "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", + "threequartersemdash","periodsuperior","questionsmall","asuperior", + "bsuperior","centsuperior","dsuperior","esuperior","isuperior", + "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", + "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", + "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", + "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", + "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", + "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", + "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", + "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", + "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", + "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", + "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", + "threeeighths","fiveeighths","seveneighths","onethird","twothirds", + "zerosuperior","foursuperior","fivesuperior","sixsuperior", + "sevensuperior","eightsuperior","ninesuperior","zeroinferior", + "oneinferior","twoinferior","threeinferior","fourinferior", + "fiveinferior","sixinferior","seveninferior","eightinferior", + "nineinferior","centinferior","dollarinferior","periodinferior", + "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", + "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", + "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", + "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", + "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", + "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", + "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", + "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", + "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", +} +local standardnames={ [0]= + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false, + "space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde",false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,"exclamdown", + "cent","sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", + "periodcentered",false,"paragraph","bullet","quotesinglbase", + "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", + false,"questiondown",false,"grave","acute","circumflex","tilde", + "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, + "hungarumlaut","ogonek","caron","emdash",false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", + "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", + false,false,false,"dotlessi",false,false,"lslash","oslash","oe", + "germandbls",false,false,false,false +} +local cffreaders={ + readbyte, + readushort, + readuint, + readulong, +} +directives.register("fonts.streamreader",function() + cffreaders={ + readbyte, + readushort, + readuint, + readulong, + } +end) +local function readheader(f) + local offset=getposition(f) + local major=readbyte(f) + local header={ + offset=offset, + major=major, + minor=readbyte(f), + size=readbyte(f), + } + if major==1 then + header.dsize=readbyte(f) + elseif major==2 then + header.dsize=readushort(f) + else + end + setposition(f,offset+header.size) + return header +end +local function readlengths(f,longcount) + local count=longcount and readulong(f) or readushort(f) + if count==0 then + return {} + end + local osize=readbyte(f) + local read=cffreaders[osize] + if not read then + report("bad offset size: %i",osize) + return {} + end + local lengths={} + local previous=read(f) + for i=1,count do + local offset=read(f) + local length=offset-previous + if length<0 then + report("bad offset: %i",length) + length=0 + end + lengths[i]=length + previous=offset + end + return lengths +end +local function readfontnames(f) + local names=readlengths(f) + for i=1,#names do + names[i]=readstring(f,names[i]) + end + return names +end +local function readtopdictionaries(f) + local dictionaries=readlengths(f) + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + return dictionaries +end +local function readstrings(f) + local lengths=readlengths(f) + local strings=setmetatableindex({},defaultstrings) + local index=#defaultstrings + for i=1,#lengths do + index=index+1 + strings[index]=readstring(f,lengths[i]) + end + return strings +end +do + local stack={} + local top=0 + local result={} + local strings={} + local p_single=P("\00")/function() + result.version=strings[stack[top]] or "unset" + top=0 + end+P("\01")/function() + result.notice=strings[stack[top]] or "unset" + top=0 + end+P("\02")/function() + result.fullname=strings[stack[top]] or "unset" + top=0 + end+P("\03")/function() + result.familyname=strings[stack[top]] or "unset" + top=0 + end+P("\04")/function() + result.weight=strings[stack[top]] or "unset" + top=0 + end+P("\05")/function() + result.fontbbox={ unpack(stack,1,4) } + top=0 + end+P("\06")/function() + result.bluevalues={ unpack(stack,1,top) } + top=0 + end+P("\07")/function() + result.otherblues={ unpack(stack,1,top) } + top=0 + end+P("\08")/function() + result.familyblues={ unpack(stack,1,top) } + top=0 + end+P("\09")/function() + result.familyotherblues={ unpack(stack,1,top) } + top=0 + end+P("\10")/function() + result.strhw=stack[top] + top=0 + end+P("\11")/function() + result.strvw=stack[top] + top=0 + end+P("\13")/function() + result.uniqueid=stack[top] + top=0 + end+P("\14")/function() + result.xuid=concat(stack,"",1,top) + top=0 + end+P("\15")/function() + result.charset=stack[top] + top=0 + end+P("\16")/function() + result.encoding=stack[top] + top=0 + end+P("\17")/function() + result.charstrings=stack[top] + top=0 + end+P("\18")/function() + result.private={ + size=stack[top-1], + offset=stack[top], + } + top=0 + end+P("\19")/function() + result.subroutines=stack[top] + top=0 + end+P("\20")/function() + result.defaultwidthx=stack[top] + top=0 + end+P("\21")/function() + result.nominalwidthx=stack[top] + top=0 + end ++P("\24")/function() + result.vstore=stack[top] + top=0 + end+P("\25")/function() + result.maxstack=stack[top] + top=0 + end + local p_double=P("\12")*( + P("\00")/function() + result.copyright=stack[top] + top=0 + end+P("\01")/function() + result.monospaced=stack[top]==1 and true or false + top=0 + end+P("\02")/function() + result.italicangle=stack[top] + top=0 + end+P("\03")/function() + result.underlineposition=stack[top] + top=0 + end+P("\04")/function() + result.underlinethickness=stack[top] + top=0 + end+P("\05")/function() + result.painttype=stack[top] + top=0 + end+P("\06")/function() + result.charstringtype=stack[top] + top=0 + end+P("\07")/function() + result.fontmatrix={ unpack(stack,1,6) } + top=0 + end+P("\08")/function() + result.strokewidth=stack[top] + top=0 + end+P("\09")/function() + result.bluescale=stack[top] + top=0 + end+P("\10")/function() + result.bluesnap=stack[top] + top=0 + end+P("\11")/function() + result.bluefuzz=stack[top] + top=0 + end+P("\12")/function() + result.stemsnaph={ unpack(stack,1,top) } + top=0 + end+P("\13")/function() + result.stemsnapv={ unpack(stack,1,top) } + top=0 + end+P("\20")/function() + result.syntheticbase=stack[top] + top=0 + end+P("\21")/function() + result.postscript=strings[stack[top]] or "unset" + top=0 + end+P("\22")/function() + result.basefontname=strings[stack[top]] or "unset" + top=0 + end+P("\21")/function() + result.basefontblend=stack[top] + top=0 + end+P("\30")/function() + result.cid.registry=strings[stack[top-2]] or "unset" + result.cid.ordering=strings[stack[top-1]] or "unset" + result.cid.supplement=stack[top] + top=0 + end+P("\31")/function() + result.cid.fontversion=stack[top] + top=0 + end+P("\32")/function() + result.cid.fontrevision=stack[top] + top=0 + end+P("\33")/function() + result.cid.fonttype=stack[top] + top=0 + end+P("\34")/function() + result.cid.count=stack[top] + top=0 + end+P("\35")/function() + result.cid.uidbase=stack[top] + top=0 + end+P("\36")/function() + result.cid.fdarray=stack[top] + top=0 + end+P("\37")/function() + result.cid.fdselect=stack[top] + top=0 + end+P("\38")/function() + result.cid.fontname=strings[stack[top]] or "unset" + top=0 + end + ) + local remap={ + ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", + ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1", + ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2", + ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3", + ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4", + ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5", + ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6", + ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7", + ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8", + ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9", + ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", + ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", + ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", + ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", + } + local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF") + local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n) + top=top+1 + stack[top]=tonumber(n) or 0 + end + local p_byte=C(R("\32\246"))/function(b0) + top=top+1 + stack[top]=byte(b0)-139 + end + local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=(byte(b0)-247)*256+byte(b1)+108 + end + local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=-(byte(b0)-251)*256-byte(b1)-108 + end + local p_short=P("\28")*C(1)*C(1)/function(b1,b2) + top=top+1 + local n=0x100*byte(b1)+byte(b2) + if n>=0x8000 then + stack[top]=n-0xFFFF-1 + else + stack[top]=n + end + end + local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) + top=top+1 + local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) + if n>=0x8000000 then + stack[top]=n-0xFFFFFFFF-1 + else + stack[top]=n + end + end + local p_unsupported=P(1)/function(detail) + top=0 + end + local p_dictionary=( + p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported + )^1 + parsedictionaries=function(data,dictionaries,version) + stack={} + strings=data.strings + if trace_charstrings then + report("charstring format %a",version) + end + for i=1,#dictionaries do + top=0 + result=version=="cff" and { + monospaced=false, + italicangle=0, + underlineposition=-100, + underlinethickness=50, + painttype=0, + charstringtype=2, + fontmatrix={ 0.001,0,0,0.001,0,0 }, + fontbbox={ 0,0,0,0 }, + strokewidth=0, + charset=0, + encoding=0, + cid={ + fontversion=0, + fontrevision=0, + fonttype=0, + count=8720, + } + } or { + charstringtype=2, + charset=0, + vstore=0, + cid={ + }, + } + lpegmatch(p_dictionary,dictionaries[i]) + dictionaries[i]=result + end + result={} + top=0 + stack={} + end + parseprivates=function(data,dictionaries) + stack={} + strings=data.strings + for i=1,#dictionaries do + local private=dictionaries[i].private + if private and private.data then + top=0 + result={ + forcebold=false, + languagegroup=0, + expansionfactor=0.06, + initialrandomseed=0, + subroutines=0, + defaultwidthx=0, + nominalwidthx=0, + cid={ + }, + } + lpegmatch(p_dictionary,private.data) + private.data=result + end + end + result={} + top=0 + stack={} + end + local x=0 + local y=0 + local width=false + local lsb=0 + local r=0 + local stems=0 + local globalbias=0 + local localbias=0 + local nominalwidth=0 + local defaultwidth=0 + local charset=false + local globals=false + local locals=false + local depth=1 + local xmin=0 + local xmax=0 + local ymin=0 + local ymax=0 + local checked=false + local keepcurve=false + local version=2 + local regions=false + local nofregions=0 + local region=false + local factors=false + local axis=false + local vsindex=0 + local justpass=false + local seacs={} + local procidx=nil + local function showstate(where) + report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) + end + local function showvalue(where,value,showstack) + if showstack then + report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) + else + report("%w%-10s : %s",depth*2,where,tostring(value)) + end + end + local function xymoveto() + if keepcurve then + r=r+1 + result[r]={ x,y,"m" } + end + if checked then + if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("rmoveto") + end + x=x+stack[top-1] + y=y+stack[top] + top=0 + xymoveto() + end + local function hmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("hmoveto") + end + x=x+stack[top] + top=0 + xmoveto() + end + local function vmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("vmoveto") + end + y=y+stack[top] + top=0 + ymoveto() + end + local function rlineto() + if trace_charstrings then + showstate("rlineto") + end + for i=1,top,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + top=0 + end + local function hlineto() + if trace_charstrings then + showstate("hlineto") + end + if top==1 then + x=x+stack[1] + xlineto() + else + local swap=true + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 + end + local function vlineto() + if trace_charstrings then + showstate("vlineto") + end + if top==1 then + y=y+stack[1] + ylineto() + else + local swap=false + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 + end + local function rrcurveto() + if trace_charstrings then + showstate("rrcurveto") + end + for i=1,top,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hhcurveto() + if trace_charstrings then + showstate("hhcurveto") + end + local s=1 + if top%2~=0 then + y=y+stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+stack[i] + local ay=y + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx+stack[i+3] + y=by + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function vvcurveto() + if trace_charstrings then + showstate("vvcurveto") + end + local s=1 + local d=0 + if top%2~=0 then + d=stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+d + local ay=y+stack[i] + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx + y=by+stack[i+3] + xycurveto(ax,ay,bx,by,x,y) + d=0 + end + top=0 + end + local function xxcurveto(swap) + local last=top%4~=0 and stack[top] + if last then + top=top-1 + end + for i=1,top,4 do + local ax,ay,bx,by + if swap then + ax=x+stack[i] + ay=y + bx=ax+stack[i+1] + by=ay+stack[i+2] + y=by+stack[i+3] + if last and i+3==top then + x=bx+last + else + x=bx + end + swap=false + else + ax=x + ay=y+stack[i] + bx=ax+stack[i+1] + by=ay+stack[i+2] + x=bx+stack[i+3] + if last and i+3==top then + y=by+last + else + y=by + end + swap=true + end + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hvcurveto() + if trace_charstrings then + showstate("hvcurveto") + end + xxcurveto(true) + end + local function vhcurveto() + if trace_charstrings then + showstate("vhcurveto") + end + xxcurveto(false) + end + local function rcurveline() + if trace_charstrings then + showstate("rcurveline") + end + for i=1,top-2,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + x=x+stack[top-1] + y=y+stack[top] + xylineto() + top=0 + end + local function rlinecurve() + if trace_charstrings then + showstate("rlinecurve") + end + if top>6 then + for i=1,top-6,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + end + local ax=x+stack[top-5] + local ay=y+stack[top-4] + local bx=ax+stack[top-3] + local by=ay+stack[top-2] + x=bx+stack[top-1] + y=by+stack[top] + xycurveto(ax,ay,bx,by,x,y) + top=0 + end + local function flex() + if trace_charstrings then + showstate("flex") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + x=ex+stack[11] + y=ey+stack[12] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex() + if trace_charstrings then + showstate("hflex") + end + local ax=x+stack[1] + local ay=y + local bx=ax+stack[2] + local by=ay+stack[3] + local cx=bx+stack[4] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[5] + local dy=by + local ex=dx+stack[6] + local ey=y + x=ex+stack[7] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex1() + if trace_charstrings then + showstate("hflex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[6] + local dy=by + local ex=dx+stack[7] + local ey=dy+stack[8] + x=ex+stack[9] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function flex1() + if trace_charstrings then + showstate("flex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + if abs(ex-x)>abs(ey-y) then + x=ex+stack[11] + else + y=ey+stack[11] + end + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function getstem() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) + if trace_charstrings then + showvalue("width",width) + end + end + top=top-1 + end + if trace_charstrings then + showstate("stem") + end + stems=stems+idiv(top,2) + top=0 + end + local function getmask() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) + if trace_charstrings then + showvalue("width",width) + end + end + top=top-1 + end + if trace_charstrings then + showstate(operator==19 and "hintmark" or "cntrmask") + end + stems=stems+idiv(top,2) + top=0 + if stems==0 then + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local function unsupported(t) + if trace_charstrings then + showstate("unsupported "..t) + end + top=0 + end + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub "..t) + end + top=0 + end + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top=0 + end + local function divide() + if version=="cff" then + local d=stack[top] + top=top-1 + stack[top]=stack[top]/d + end + end + local function closepath() + if version=="cff" then + if trace_charstrings then + showstate("closepath") + end + end + top=0 + end + local function hsbw() + if version=="cff" then + if trace_charstrings then + showstate("hsbw") + end + lsb=stack[top-1] or 0 + width=stack[top] + end + top=0 + end + local function sbw() + if version=="cff" then + if trace_charstrings then + showstate("sbw") + end + lsb=stack[top-3] + width=stack[top-1] + end + top=0 + end + local function seac() + if version=="cff" then + if trace_charstrings then + showstate("seac") + end + end + top=0 + end + local popped=3 + local hints=3 + local function callothersubr() + if version=="cff" then + if trace_charstrings then + showstate("callothersubr") + end + if stack[top]==hints then + popped=stack[top-2] + else + popped=3 + end + local t=stack[top-1] + if t then + top=top-(t+2) + if top<0 then + top=0 + end + else + top=0 + end + else + top=0 + end + end + local function pop() + if version=="cff" then + if trace_charstrings then + showstate("pop") + end + top=top+1 + stack[top]=popped + else + top=0 + end + end + local function setcurrentpoint() + if version=="cff" then + if trace_charstrings then + showstate("setcurrentpoint (unsupported)") + end + x=x+stack[top-1] + y=y+stack[top] + end + top=0 + end + local reginit=false + local function updateregions(n) + if regions then + local current=regions[n] or regions[1] + nofregions=#current + if axis and n~=reginit then + factors={} + for i=1,nofregions do + local region=current[i] + local s=1 + for j=1,#axis do + local f=axis[j] + local r=region[j] + local start=r.start + local peak=r.peak + local stop=r.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + factors[i]=s + end + end + end + reginit=n + end + local function setvsindex() + local vsindex=stack[top] + if trace_charstrings then + showstate(formatters["vsindex %i"](vsindex)) + end + updateregions(vsindex) + top=top-1 + end + local function blend() + local n=stack[top] + top=top-1 + if axis then + if trace_charstrings then + local t=top-nofregions*n + local m=t-n + for i=1,n do + local k=m+i + local d=m+n+(i-1)*nofregions + local old=stack[k] + local new=old + for r=1,nofregions do + new=new+stack[d+r]*factors[r] + end + stack[k]=new + showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) + end + top=t + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=v + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=v + d=d+nofregions + end + end + else + top=top-nofregions*n + end + end + local actions={ [0]=unsupported, + getstem, + unsupported, + getstem, + vmoveto, + rlineto, + hlineto, + vlineto, + rrcurveto, + unsupported, + unsupported, + unsupported, + unsupported, + hsbw, + unsupported, + setvsindex, + blend, + unsupported, + getstem, + getmask, + getmask, + rmoveto, + hmoveto, + getstem, + rcurveline, + rlinecurve, + vvcurveto, + hhcurveto, + unsupported, + unsupported, + vhcurveto, + hvcurveto, + } + local reverse={ [0]="unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } + local subactions={ + [000]=dotsection, + [001]=getstem3, + [002]=getstem3, + [006]=seac, + [007]=sbw, + [012]=divide, + [016]=callothersubr, + [017]=pop, + [033]=setcurrentpoint, + [034]=hflex, + [035]=flex, + [036]=hflex1, + [037]=flex1, + } + local chars=setmetatableindex(function (t,k) + local v=char(k) + t[k]=v + return v + end) + local c_endchar=chars[14] + local encode={} + setmetatableindex(encode,function(t,i) + for i=-2048,-1130 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v=0xFB00-i-108 + t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i]=chars[i+139] + end + for i=108,1131 do + local v=0xF700+i-108 + t[i]=char(extract(v,8,8),extract(v,0,8)) + end + for i=1132,2048 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + setmetatableindex(encode,function(t,k) + local r=round(k) + local v=rawget(t,r) + if v then + return v + end + local v1=floor(k) + local v2=floor((k-v1)*0x10000) + return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) + end) + return t[i] + end) + readers.cffencoder=encode + local function p_setvsindex() + local vsindex=stack[top] + updateregions(vsindex) + top=top-1 + end + local function p_blend() + local n=stack[top] + top=top-1 + if not axis then + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=round(v) + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=round(v) + d=d+nofregions + end + end + end + local function p_getstem() + local n=0 + if top%2~=0 then + n=1 + end + if top>n then + stems=stems+idiv(top-n,2) + end + end + local function p_getmask() + local n=0 + if top%2~=0 then + n=1 + end + if top>n then + stems=stems+idiv(top-n,2) + end + if stems==0 then + return 0 + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local process + local function call(scope,list,bias) + depth=depth+1 + if top==0 then + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) + top=0 + else + local index=stack[top]+bias + top=top-1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab=list[index] + if tab then + process(tab) + else + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) + top=0 + end + end + depth=depth-1 + end + process=function(tab) + local i=1 + local n=#tab + while i<=n do + local t=tab[i] + if t>=32 then + top=top+1 + if t<=246 then + stack[top]=t-139 + i=i+1 + elseif t<=250 then + stack[top]=t*256-63124+tab[i+1] + i=i+2 + elseif t<=254 then + stack[top]=-t*256+64148-tab[i+1] + i=i+2 + else + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF + else + stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF + end + i=i+5 + end + elseif t==28 then + top=top+1 + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000 + else + stack[top]=n + end + i=i+3 + elseif t==11 then + if trace_charstrings then + showstate("return") + end + return + elseif t==10 then + call("local",locals,localbias) + i=i+1 + elseif t==14 then + if width then + elseif top>0 then + width=stack[1] + if trace_charstrings then + showvalue("width",width) + end + else + width=true + end + if trace_charstrings then + showstate("endchar") + end + return + elseif t==29 then + call("global",globals,globalbias) + i=i+1 + elseif t==12 then + i=i+1 + local t=tab[i] + if justpass then + if t>=34 and t<=37 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + r=r+1;result[r]=chars[12] + r=r+1;result[r]=chars[t] + top=0 + elseif t==6 then + seacs[procidx]={ + asb=stack[1], + adx=stack[2], + ady=stack[3], + base=stack[4], + accent=stack[5], + width=width, + lsb=lsb, + } + top=0 + else + local a=subactions[t] + if a then + a(t) + else + top=0 + end + end + else + local a=subactions[t] + if a then + a(t) + else + if trace_charstrings then + showvalue("",t) + end + top=0 + end + end + i=i+1 + elseif justpass then + if t==15 then + p_setvsindex() + i=i+1 + elseif t==16 then + local s=p_blend() or 0 + i=i+s+1 + elseif t==1 or t==3 or t==18 or operation==23 then + p_getstem() + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + else + top=0 + end + i=i+1 + elseif t==19 or t==20 then + local s=p_getmask() or 0 + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + for j=1,s do + i=i+1 + r=r+1;result[r]=chars[tab[i]] + end + else + i=i+s + top=0 + end + i=i+1 + elseif t==9 then + top=0 + i=i+1 + elseif t==13 then + hsbw() + if version=="cff" then + r=r+1;result[r]=encode[lsb] + r=r+1;result[r]=chars[22] + else + end + i=i+1 + else + if trace_charstrings then + showstate(reverse[t] or "") + end + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 + end + r=r+1;result[r]=chars[t] + i=i+1 + end + else + local a=actions[t] + if a then + local s=a(t) + if s then + i=i+s+1 + else + i=i+1 + end + else + if trace_charstrings then + showstate(reverse[t] or "") + end + top=0 + i=i+1 + end + end + end + end + local function setbias(globals,locals,nobias) + if nobias then + return 0,0 + else + local g=#globals + local l=#locals + return + ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, + ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 + end + end + local function processshape(tab,index,hack) + if not tab then + glyphs[index]={ + boundingbox={ 0,0,0,0 }, + width=0, + name=charset and charset[index] or nil, + } + return + end + tab=bytetable(tab) + x=0 + y=0 + width=false + lsb=0 + r=0 + top=0 + stems=0 + result={} + popped=3 + procidx=index + xmin=0 + xmax=0 + ymin=0 + ymax=0 + checked=false + if trace_charstrings then + report("glyph: %i",index) + report("data : % t",tab) + end + if regions then + updateregions(vsindex) + end + process(tab) + if hack then + return x,y + end + local boundingbox={ + round(xmin), + round(ymin), + round(xmax), + round(ymax), + } + if width==true or width==false then + width=defaultwidth + else + width=nominalwidth+width + end + local glyph=glyphs[index] + if justpass then + r=r+1 + result[r]=c_endchar + local stream=concat(result) + if glyph then + glyph.stream=stream + else + glyphs[index]={ stream=stream } + end + elseif glyph then + glyph.segments=keepcurve~=false and result or nil + glyph.boundingbox=boundingbox + if not glyph.width then + glyph.width=width + end + if charset and not glyph.name then + glyph.name=charset[index] + end + elseif keepcurve then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + end + if trace_charstrings then + report("width : %s",tostring(width)) + report("boundingbox: % t",boundingbox) + end + end + startparsing=function(fontdata,data,streams) + reginit=false + axis=false + regions=data.regions + justpass=streams==true + popped=3 + seacs={} + if regions then + regions={ regions } + axis=data.factors or false + end + end + stopparsing=function(fontdata,data) + stack={} + glyphs=false + result={} + top=0 + locals=false + globals=false + strings=false + popped=3 + seacs={} + end + local function setwidths(private) + if not private then + return 0,0 + end + local privatedata=private.data + if not privatedata then + return 0,0 + end + return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 + end + parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias) + local dictionary=data.dictionaries[1] + local charstrings=dictionary.charstrings + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=dictionary.charset + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + globalbias,localbias=setbias(globals,locals,nobias) + nominalwidth,defaultwidth=setwidths(dictionary.private) + if charstrings then + startparsing(fontdata,data,streams) + for index=1,#charstrings do + processshape(charstrings[index],index-1) + end + if justpass and next(seacs) then + local charset=data.dictionaries[1].charset + if charset then + local lookup=table.swapped(charset) + for index,v in next,seacs do + local bindex=lookup[standardnames[v.base]] + local aindex=lookup[standardnames[v.accent]] + local bglyph=bindex and glyphs[bindex] + local aglyph=aindex and glyphs[aindex] + if bglyph and aglyph then + local jp=justpass + justpass=false + local x,y=processshape(charstrings[bindex+1],bindex,true) + justpass=jp + local base=bglyph.stream + local accent=aglyph.stream + local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] + base=sub(base,1,#base-1) + glyphs[index].stream=base..moveto..accent + end + end + end + end + stopparsing(fontdata,data) + else + report("no charstrings") + end + return glyphs + end + parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=false + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + justpass=streams==true + seacs={} + globalbias,localbias=setbias(globals,locals,nobias) + nominalwidth,defaultwidth=setwidths(dictionary.private) + processshape(tab,index-1) + end +end +local function readglobals(f,data,version) + local routines=readlengths(f,version=="cff2") + for i=1,#routines do + routines[i]=readbytetable(f,routines[i]) + end + data.routines=routines +end +local function readencodings(f,data) + data.encodings={} +end +local function readcharsets(f,data,dictionary) + local header=data.header + local strings=data.strings + local nofglyphs=data.nofglyphs + local charsetoffset=dictionary.charset + if charsetoffset and charsetoffset~=0 then + setposition(f,header.offset+charsetoffset) + local format=readbyte(f) + local charset={ [0]=".notdef" } + dictionary.charset=charset + if format==0 then + for i=1,nofglyphs do + charset[i]=strings[readushort(f)] + end + elseif format==1 or format==2 then + local readcount=format==1 and readbyte or readushort + local i=1 + while i<=nofglyphs do + local sid=readushort(f) + local n=readcount(f) + for s=sid,sid+n do + charset[i]=strings[s] + i=i+1 + if i>nofglyphs then + break + end + end + end + else + report("cff parser: unsupported charset format %a",format) + end + else + dictionary.nocharset=true + dictionary.charset=nil + end +end +local function readprivates(f,data) + local header=data.header + local dictionaries=data.dictionaries + local private=dictionaries[1].private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) + end +end +local function readlocals(f,data,dictionary,version) + local header=data.header + local private=dictionary.private + if private then + local subroutineoffset=private.data.subroutines + if subroutineoffset~=0 then + setposition(f,header.offset+private.offset+subroutineoffset) + local subroutines=readlengths(f,version=="cff2") + for i=1,#subroutines do + subroutines[i]=readbytetable(f,subroutines[i]) + end + dictionary.subroutines=subroutines + private.data.subroutines=nil + else + dictionary.subroutines={} + end + else + dictionary.subroutines={} + end +end +local function readcharstrings(f,data,version) + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local stringtype=dictionary.charstringtype + local offset=dictionary.charstrings + if type(offset)~="number" then + elseif stringtype==2 then + setposition(f,header.offset+offset) + local charstrings=readlengths(f,version=="cff2") + local nofglyphs=#charstrings + for i=1,nofglyphs do + charstrings[i]=readstring(f,charstrings[i]) + end + data.nofglyphs=nofglyphs + dictionary.charstrings=charstrings + else + report("unsupported charstr type %i",stringtype) + data.nofglyphs=0 + dictionary.charstrings={} + end +end +local function readcidprivates(f,data) + local header=data.header + local dictionaries=data.dictionaries[1].cid.dictionaries + for i=1,#dictionaries do + local dictionary=dictionaries[i] + local private=dictionary.private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) + end + end + parseprivates(data,dictionaries) +end +readers.parsecharstrings=parsecharstrings +local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local cid=not dictionary.private and dictionary.cid + readglobals(f,data,version) + readcharstrings(f,data,version) + if version=="cff2" then + dictionary.charset=nil + else + readencodings(f,data) + readcharsets(f,data,dictionary) + end + if cid then + local fdarray=cid.fdarray + if fdarray then + setposition(f,data.header.offset+fdarray) + local dictionaries=readlengths(f,version=="cff2") + local nofdictionaries=#dictionaries + if nofdictionaries>0 then + for i=1,nofdictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + dictionary.private=dictionaries[1].private + if nofdictionaries>1 then + report("ignoring dictionaries > 1 in cid font") + end + end + end + end + readprivates(f,data) + parseprivates(data,data.dictionaries) + readlocals(f,data,dictionary,version) + startparsing(fontdata,data,streams) + parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) + stopparsing(fontdata,data) +end +local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local cid=dictionary.cid + local cidselect=cid and cid.fdselect + readglobals(f,data,version) + readcharstrings(f,data,version) + if version~="cff2" then + readencodings(f,data) + end + local charstrings=dictionary.charstrings + local fdindex={} + local nofglyphs=data.nofglyphs + local maxindex=-1 + setposition(f,header.offset+cidselect) + local format=readbyte(f) + if format==1 then + for i=0,nofglyphs do + local index=readbyte(f) + fdindex[i]=index + if index>maxindex then + maxindex=index + end + end + elseif format==3 then + local nofranges=readushort(f) + local first=readushort(f) + local index=readbyte(f) + while true do + local last=readushort(f) + if index>maxindex then + maxindex=index + end + for i=first,last do + fdindex[i]=index + end + if last>=nofglyphs then + break + else + first=last+1 + index=readbyte(f) + end + end + else + end + if maxindex>=0 then + local cidarray=cid.fdarray + if cidarray then + setposition(f,header.offset+cidarray) + local dictionaries=readlengths(f,version=="cff2") + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + cid.dictionaries=dictionaries + readcidprivates(f,data) + for i=1,#dictionaries do + readlocals(f,data,dictionaries[i],version) + end + startparsing(fontdata,data,streams) + for i=1,#charstrings do + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) + end + stopparsing(fontdata,data) + else + report("no cid array") + end + end +end +local gotodatatable=readers.helpers.gotodatatable +local function cleanup(data,dictionaries) +end +function readers.cff(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local glyphs=fontdata.glyphs + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff") + local dic=dictionaries[1] + local cid=dic.cid + local cffinfo={ + familyname=dic.familyname, + fullname=dic.fullname, + boundingbox=dic.boundingbox, + weight=dic.weight, + italicangle=dic.italicangle, + underlineposition=dic.underlineposition, + underlinethickness=dic.underlinethickness, + defaultwidth=dic.defaultwidthx, + nominalwidth=dic.nominalwidthx, + monospaced=dic.monospaced, + } + fontdata.cidinfo=cid and { + registry=cid.registry, + ordering=cid.ordering, + supplement=cid.supplement, + } + fontdata.cffinfo=cffinfo + local all=specification.shapes or specification.streams or false + if specification.glyphs or all then + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + end + end + local private=dic.private + if private then + local data=private.data + if type(data)=="table" then + cffinfo.defaultwidth=data.defaultwidthx or cffinfo.defaultwidth + cffinfo.nominalwidth=data.nominalwidthx or cffinfo.nominalwidth + cffinfo.bluevalues=data.bluevalues + cffinfo.otherblues=data.otherblues + cffinfo.familyblues=data.familyblues + cffinfo.familyotherblues=data.familyotherblues + cffinfo.bluescale=data.bluescale + cffinfo.blueshift=data.blueshift + cffinfo.bluefuzz=data.bluefuzz + cffinfo.stdhw=data.stdhw + cffinfo.stdvw=data.stdvw + end + end + cleanup(data,dictionaries) + end +end +function readers.cff2(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=2 then + report("only version %s is supported for table %a",2,"cff2") + return + end + local glyphs=fontdata.glyphs + local dictionaries={ readstring(f,header.dsize) } + local data={ + header=header, + dictionaries=dictionaries, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff2") + local offset=dictionaries[1].vstore + if offset>0 then + local storeoffset=dictionaries[1].vstore+data.header.offset+2 + local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) + data.regions=regions + data.deltas=deltas + else + data.regions={} + data.deltas={} + end + data.factors=specification.factors + local cid=data.dictionaries[1].cid + local all=specification.shapes or specification.streams or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + end + cleanup(data,dictionaries) + end +end +function readers.cffcheck(filename) + local f=io.open(filename,"rb") + if f then + local fontdata={ + glyphs={}, + } + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local glyphs={} + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + glyphs=glyphs, + nofglyphs=0, + } + parsedictionaries(data,dictionaries,"cff") + local cid=data.dictionaries[1].cid + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,false) + else + readnoselect(f,fontdata,data,glyphs,false) + end + return data + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf” ffffc827e1bcddc33a2b615340ecff7f] --- + +if not modules then modules={} end modules ['font-ttf']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,unpack=next,type,unpack +local band,rshift=bit32.band,bit32.rshift +local sqrt,round=math.sqrt,math.round +local char,rep=string.char,string.rep +local concat=table.concat +local idiv=number.idiv +local setmetatableindex=table.setmetatableindex +local report=logs.reporter("otf reader","ttf") +local trace_deltas=false +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local skipbytes=streamreader.skip +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 +local readchar=streamreader.readinteger1 +local readshort=streamreader.readinteger2 +local read2dot14=streamreader.read2dot14 +local readinteger=streamreader.readinteger1 +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + skipbytes=streamreader.skip + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readchar=streamreader.readinteger1 + readshort=streamreader.readinteger2 + read2dot14=streamreader.read2dot14 + readinteger=streamreader.readinteger1 + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable +end) +local short=2 +local ushort=2 +local ulong=4 +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable +local function mergecomposites(glyphs,shapes) + local function merge(index,shape,components) + local contours={} + local points={} + local nofcontours=0 + local nofpoints=0 + local offset=0 + local deltas=shape.deltas + for i=1,#components do + local component=components[i] + local subindex=component.index + local subshape=shapes[subindex] + local subcontours=subshape.contours + local subpoints=subshape.points + if not subcontours then + local subcomponents=subshape.components + if subcomponents then + subcontours,subpoints=merge(subindex,subshape,subcomponents) + end + end + if subpoints then + local matrix=component.matrix + local xscale=matrix[1] + local xrotate=matrix[2] + local yrotate=matrix[3] + local yscale=matrix[4] + local xoffset=matrix[5] + local yoffset=matrix[6] + local count=#subpoints + if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then + for i=1,count do + local p=subpoints[i] + nofpoints=nofpoints+1 + points[nofpoints]={ + p[1]+xoffset, + p[2]+yoffset, + p[3] + } + end + else + for i=1,count do + local p=subpoints[i] + local x=p[1] + local y=p[2] + nofpoints=nofpoints+1 + points[nofpoints]={ + xscale*x+xrotate*y+xoffset, + yscale*y+yrotate*x+yoffset, + p[3] + } + end + end + local subcount=#subcontours + if subcount==1 then + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[1] + else + for i=1,#subcontours do + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[i] + end + end + offset=offset+count + else + report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) + end + end + shape.points=points + shape.contours=contours + shape.components=nil + return contours,points + end + for index=0,#glyphs do + local shape=shapes[index] + if shape then + local components=shape.components + if components then + merge(index,shape,components) + end + end + end +end +local function readnothing(f) + return { + type="nothing", + } +end +local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) + return + l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), + r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), + r_x,r_y,"c" +end +local function applyaxis(glyph,shape,deltas,dowidth) + local points=shape.points + if points then + local nofpoints=#points + local h=nofpoints+2 + local l=nofpoints+1 + local dw=0 + local dl=0 + for i=1,#deltas do + local deltaset=deltas[i] + local xvalues=deltaset.xvalues + local yvalues=deltaset.yvalues + local dpoints=deltaset.points + local factor=deltaset.factor + if dpoints then + local nofdpoints=#dpoints + for i=1,nofdpoints do + local d=dpoints[i] + local p=points[d] + if p then + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + elseif dowidth then + if d==h then + local x=xvalues[i] + if x then + dw=dw+factor*x + end + elseif d==l then + local x=xvalues[i] + if x then + dl=dl+factor*x + end + end + end + end + else + for i=1,nofpoints do + local p=points[i] + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + end + if dowidth then + local x=xvalues[h] + if x then + dw=dw+factor*x + end + local x=xvalues[l] + if x then + dl=dl+factor*x + end + end + end + end + if dowidth then + local width=glyph.width or 0 + glyph.width=width+dw-dl + end + else + report("no points for glyph %a",glyph.name) + end +end +local quadratic=false +local function contours2outlines_normal(glyphs,shapes) + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments={} + local nofsegments=0 + glyph.segments=segments + if nofcontours>0 then + local px=0 + local py=0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin=x + ymin=y + xmax=x + ymax=y + done=true + end + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x,y=current_pt[1],current_pt[2] + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + if not quadratic then + px,py=x,y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + else + nofsegments=nofsegments+1 + local x2=first_pt[1] + local y2=first_pt[2] + if not control_pt then + segments[nofsegments]={ x2,y2,"l" } + elseif quadratic then + local x1=control_pt[1] + local y1=control_pt[2] + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + local x1=control_pt[1] + local y1=control_pt[2] + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + end + end + first=last+1 + end + end + end + end + end +end +local function contours2outlines_shaped(glyphs,shapes,keepcurve) + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments=keepcurve and {} or nil + local nofsegments=0 + if keepcurve then + glyph.segments=segments + end + if nofcontours>0 then + local xmin,ymin,xmax,ymax,done=0,0,0,0,false + local px,py=0,0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + if keepcurve then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + end + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin,ymin,xmax,ymax=x,y,x,y + done=true + else + if xxmax then xmax=x end + if yymax then ymax=y end + end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + end + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x=current_pt[1] + local y=current_pt[2] + if xxmax then xmax=x end + if yymax then ymax=y end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + end + if not quadratic then + px=x + py=y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + elseif not control_pt then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ first_pt[1],first_pt[2],"l" } + end + else + local x1=control_pt[1] + local y1=control_pt[2] + local x2=first_pt[1] + local y2=first_pt[2] + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if quadratic then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + end + end + end + first=last+1 + end + glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } + end + end + end + end +end +local c_zero=char(0) +local s_zero=char(0,0) +local function toushort(n) + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local function toshort(n) + if n<0 then + n=n+0x10000 + end + return char(band(rshift(n,8),0xFF),band(n,0xFF)) +end +local chars=setmetatableindex(function(t,k) + for i=0,255 do local v=char(i) t[i]=v end return t[k] +end) +local function repackpoints(glyphs,shapes) + local noboundingbox={ 0,0,0,0 } + local result={} + local xpoints={} + local ypoints={} + for index=0,#glyphs do + local shape=shapes[index] + if shape then + local r=0 + local glyph=glyphs[index] + local contours=shape.contours + local nofcontours=contours and #contours or 0 + local boundingbox=glyph.boundingbox or noboundingbox + r=r+1 result[r]=toshort(nofcontours) + r=r+1 result[r]=toshort(boundingbox[1]) + r=r+1 result[r]=toshort(boundingbox[2]) + r=r+1 result[r]=toshort(boundingbox[3]) + r=r+1 result[r]=toshort(boundingbox[4]) + if nofcontours>0 then + for i=1,nofcontours do + r=r+1 result[r]=toshort(contours[i]-1) + end + r=r+1 result[r]=s_zero + local points=shape.points + local currentx=0 + local currenty=0 + local x=0 + local y=0 + local lastflag=nil + local nofflags=0 + for i=1,#points do + local pt=points[i] + local px=pt[1] + local py=pt[2] + local fl=pt[3] and 0x01 or 0x00 + if px==currentx then + fl=fl+0x10 + else + local dx=round(px-currentx) + x=x+1 + if dx<-255 or dx>255 then + xpoints[x]=toshort(dx) + elseif dx<0 then + fl=fl+0x02 + xpoints[x]=chars[-dx] + elseif dx>0 then + fl=fl+0x12 + xpoints[x]=chars[dx] + else + fl=fl+0x02 + xpoints[x]=c_zero + end + end + if py==currenty then + fl=fl+0x20 + else + local dy=round(py-currenty) + y=y+1 + if dy<-255 or dy>255 then + ypoints[y]=toshort(dy) + elseif dy<0 then + fl=fl+0x04 + ypoints[y]=chars[-dy] + elseif dy>0 then + fl=fl+0x24 + ypoints[y]=chars[dy] + else + fl=fl+0x04 + ypoints[y]=c_zero + end + end + currentx=px + currenty=py + if lastflag==fl then + if nofflags==255 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + nofflags=1 + lastflag=fl + else + nofflags=nofflags+1 + end + else + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + nofflags=1 + lastflag=fl + end + end + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + r=r+1 result[r]=concat(xpoints,"",1,x) + r=r+1 result[r]=concat(ypoints,"",1,y) + end + local stream=concat(result,"",1,r) + local length=#stream + local padding=idiv(length+3,4)*4-length + if padding>0 then + if padding==1 then + padding="\0" + elseif padding==2 then + padding="\0\0" + else + padding="\0\0\0" + end + padding=stream..padding + end + glyph.stream=stream + end + end +end +local flags={} +local function readglyph(f,nofcontours) + local points={} + local contours={} + for i=1,nofcontours do + contours[i]=readshort(f)+1 + end + local nofpoints=contours[nofcontours] + local nofinstructions=readushort(f) + skipbytes(f,nofinstructions) + local i=1 + while i<=nofpoints do + local flag=readbyte(f) + flags[i]=flag + if band(flag,0x08)~=0 then + local n=readbyte(f) + if n==1 then + i=i+1 + flags[i]=flag + else + for j=1,n do + i=i+1 + flags[i]=flag + end + end + end + i=i+1 + end + local x=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x02)~=0 then + if band(flag,0x10)~=0 then + x=x+readbyte(f) + else + x=x-readbyte(f) + end + elseif band(flag,0x10)~=0 then + else + x=x+readshort(f) + end + points[i]={ x,0,band(flag,0x01)~=0 } + end + local y=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x04)~=0 then + if band(flag,0x20)~=0 then + y=y+readbyte(f) + else + y=y-readbyte(f) + end + elseif band(flag,0x20)~=0 then + else + y=y+readshort(f) + end + points[i][2]=y + end + return { + type="glyph", + points=points, + contours=contours, + nofpoints=nofpoints, + } +end +local function readcomposite(f) + local components={} + local nofcomponents=0 + local instructions=false + while true do + local flags=readushort(f) + local index=readushort(f) + local f_xyarg=band(flags,0x0002)~=0 + local f_offset=band(flags,0x0800)~=0 + local xscale=1 + local xrotate=0 + local yrotate=0 + local yscale=1 + local xoffset=0 + local yoffset=0 + local base=false + local reference=false + if f_xyarg then + if band(flags,0x0001)~=0 then + xoffset=readshort(f) + yoffset=readshort(f) + else + xoffset=readchar(f) + yoffset=readchar(f) + end + else + if band(flags,0x0001)~=0 then + base=readshort(f) + reference=readshort(f) + else + base=readchar(f) + reference=readchar(f) + end + end + if band(flags,0x0008)~=0 then + xscale=read2dot14(f) + yscale=xscale + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0040)~=0 then + xscale=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0080)~=0 then + xscale=read2dot14(f) + xrotate=read2dot14(f) + yrotate=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*sqrt(xscale^2+xrotate^2) + yoffset=yoffset*sqrt(yrotate^2+yscale^2) + end + end + nofcomponents=nofcomponents+1 + components[nofcomponents]={ + index=index, + usemine=band(flags,0x0200)~=0, + round=band(flags,0x0006)~=0, + base=base, + reference=reference, + matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, + } + if band(flags,0x0100)~=0 then + instructions=true + end + if band(flags,0x0020)==0 then + break + end + end + return { + type="composite", + components=components, + } +end +function readers.loca(f,fontdata,specification) + if specification.glyphs then + local datatable=fontdata.tables.loca + if datatable then + local offset=fontdata.tables.glyf.offset + local format=fontdata.fontheader.indextolocformat + local profile=fontdata.maximumprofile + local nofglyphs=profile and profile.nofglyphs + local locations={} + setposition(f,datatable.offset) + if format==1 then + if not nofglyphs then + nofglyphs=idiv(datatable.length,4)-1 + end + for i=0,nofglyphs do + locations[i]=offset+readulong(f) + end + fontdata.nofglyphs=nofglyphs + else + if not nofglyphs then + nofglyphs=idiv(datatable.length,2)-1 + end + for i=0,nofglyphs do + locations[i]=offset+readushort(f)*2 + end + end + fontdata.nofglyphs=nofglyphs + fontdata.locations=locations + end + end +end +function readers.glyf(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) + if tableoffset then + local locations=fontdata.locations + if locations then + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local filesize=fontdata.filesize + local nothing={ 0,0,0,0 } + local shapes={} + local loadshapes=specification.shapes or specification.instance or specification.streams + for index=0,nofglyphs-1 do + local location=locations[index] + local length=locations[index+1]-location + if location>=filesize then + report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) + fontdata.nofglyphs=index-1 + fontdata.badfont=true + break + elseif length>0 then + setposition(f,location) + local nofcontours=readshort(f) + glyphs[index].boundingbox={ + readshort(f), + readshort(f), + readshort(f), + readshort(f), + } + if not loadshapes then + elseif nofcontours==0 then + shapes[index]=readnothing(f) + elseif nofcontours>0 then + shapes[index]=readglyph(f,nofcontours) + else + shapes[index]=readcomposite(f,nofcontours) + end + else + if loadshapes then + shapes[index]=readnothing(f) + end + glyphs[index].boundingbox=nothing + end + end + if loadshapes then + if readers.gvar then + readers.gvar(f,fontdata,specification,glyphs,shapes) + end + mergecomposites(glyphs,shapes) + if specification.instance then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_shaped(glyphs,shapes,specification.shapes) + end + elseif specification.shapes then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_normal(glyphs,shapes) + end + elseif specification.streams then + repackpoints(glyphs,shapes) + end + end + end + end +end +local function readtuplerecord(f,nofaxis) + local record={} + for i=1,nofaxis do + record[i]=read2dot14(f) + end + return record +end +local function readpoints(f) + local count=readbyte(f) + if count==0 then + return nil,0 + else + if count<128 then + elseif band(count,0x80)~=0 then + count=band(count,0x7F)*256+readbyte(f) + else + end + local points={} + local p=0 + local n=1 + while p0 do + local control=readbyte(f) +if not control then + break +end + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + z=z+runlength + else + local runreader=band(control,0x40)~=0 and readshort or readinteger + if z>0 then + for i=1,z do + p=p+1 + deltas[p]=0 + end + z=0 + end + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + end + if p>0 then + return deltas + else + end +end +local function readdeltas(f,nofpoints) + local deltas={} + local p=0 + while nofpoints>0 do + local control=readbyte(f) + if control then + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + for i=1,runlength do + p=p+1 + deltas[p]=0 + end + else + local runreader=band(control,0x40)~=0 and readshort or readinteger + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + else + break + end + end + if p>0 then + return deltas + else + end +end +function readers.gvar(f,fontdata,specification,glyphdata,shapedata) + local instance=specification.instance + if not instance then + return + end + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) + if tableoffset then + local version=readulong(f) + local nofaxis=readushort(f) + local noftuples=readushort(f) + local tupleoffset=tableoffset+readulong(f) + local nofglyphs=readushort(f) + local flags=readushort(f) + local dataoffset=tableoffset+readulong(f) + local data={} + local tuples={} + local glyphdata=fontdata.glyphs + local dowidth=not fontdata.variabledata.hvarwidths + if band(flags,0x0001)~=0 then + for i=1,nofglyphs+1 do + data[i]=dataoffset+readulong(f) + end + else + for i=1,nofglyphs+1 do + data[i]=dataoffset+2*readushort(f) + end + end + if noftuples>0 then + setposition(f,tupleoffset) + for i=1,noftuples do + tuples[i]=readtuplerecord(f,nofaxis) + end + end + local nextoffset=false + local startoffset=data[1] + for i=1,nofglyphs do + nextoffset=data[i+1] + local glyph=glyphdata[i-1] + local name=trace_deltas and glyph.name + if startoffset==nextoffset then + if name then + report("no deltas for glyph %a",name) + end + else + local shape=shapedata[i-1] + if not shape then + if name then + report("no shape for glyph %a",name) + end + else + lastoffset=startoffset + setposition(f,startoffset) + local flags=readushort(f) + local count=band(flags,0x0FFF) + local offset=startoffset+readushort(f) + local deltas={} + local allpoints=(shape.nofpoints or 0) + local shared=false + local nofshared=0 + if band(flags,0x8000)~=0 then + local current=getposition(f) + setposition(f,offset) + shared,nofshared=readpoints(f) + offset=getposition(f) + setposition(f,current) + end + for j=1,count do + local size=readushort(f) + local flags=readushort(f) + local index=band(flags,0x0FFF) + local haspeak=band(flags,0x8000)~=0 + local intermediate=band(flags,0x4000)~=0 + local private=band(flags,0x2000)~=0 + local peak=nil + local start=nil + local stop=nil + local xvalues=nil + local yvalues=nil + local points=shared + local nofpoints=nofshared + if haspeak then + peak=readtuplerecord(f,nofaxis) + else + if index+1>#tuples then + report("error, bad tuple index",index) + end + peak=tuples[index+1] + end + if intermediate then + start=readtuplerecord(f,nofaxis) + stop=readtuplerecord(f,nofaxis) + end + if size>0 then + local current=getposition(f) + setposition(f,offset) + if private then + points,nofpoints=readpoints(f) + end + if nofpoints==0 then + nofpoints=allpoints+4 + end + if nofpoints>0 then + xvalues=readdeltas(f,nofpoints) + yvalues=readdeltas(f,nofpoints) + end + offset=offset+size + setposition(f,current) + end + if not xvalues and not yvalues then + points=nil + end + local s=1 + for i=1,nofaxis do + local f=factors[i] + local peak=peak and peak [i] or 0 + local start=start and start[i] or (peak<0 and peak or 0) + local stop=stop and stop [i] or (peak>0 and peak or 0) + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + if s==0 then + if name then + report("no deltas applied for glyph %a",name) + end + else + deltas[#deltas+1]={ + factor=s, + points=points, + xvalues=xvalues, + yvalues=yvalues, + } + end + end + if shape.type=="glyph" then + applyaxis(glyph,shape,deltas,dowidth) + else + shape.deltas=deltas + end + end + end + startoffset=nextoffset + end + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp” 18c85a4857f45c31a3555bf1faac434a] --- + +if not modules then modules={} end modules ['font-dsp']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber=next,type,tonumber +local band=bit32.band +local extract=bit32.extract +local bor=bit32.bor +local lshift=bit32.lshift +local rshift=bit32.rshift +local gsub=string.gsub +local lower=string.lower +local sub=string.sub +local strip=string.strip +local tohash=table.tohash +local concat=table.concat +local copy=table.copy +local reversed=table.reversed +local sort=table.sort +local insert=table.insert +local round=math.round +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too +local setmetatableindex=table.setmetatableindex +local formatters=string.formatters +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local sequenced=table.sequenced +local report=logs.reporter("otf reader") +local readers=fonts.handlers.otf.readers +local streamreader=readers.streamreader +local setposition=streamreader.setposition +local getposition=streamreader.getposition +local readuinteger=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 +local readinteger=streamreader.readinteger1 +local readshort=streamreader.readinteger2 +local readstring=streamreader.readstring +local readtag=streamreader.readtag +local readbytes=streamreader.readbytes +local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 +local skipshort=streamreader.skipshort +local skipbytes=streamreader.skip +local readbytetable=streamreader.readbytetable +local readbyte=streamreader.readbyte +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +local readfword=readshort +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + readuinteger=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readinteger=streamreader.readinteger1 + readshort=streamreader.readinteger2 + readstring=streamreader.readstring + readtag=streamreader.readtag + readbytes=streamreader.readbytes + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + skipshort=streamreader.skipshort + skipbytes=streamreader.skip + readbytetable=streamreader.readbytetable + readbyte=streamreader.readbyte + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + readfword=readshort +end) +local gsubhandlers={} +local gposhandlers={} +readers.gsubhandlers=gsubhandlers +readers.gposhandlers=gposhandlers +local helpers=readers.helpers +local gotodatatable=helpers.gotodatatable +local setvariabledata=helpers.setvariabledata +local lookupidoffset=-1 +local classes={ + "base", + "ligature", + "mark", + "component", +} +local gsubtypes={ + "single", + "multiple", + "alternate", + "ligature", + "context", + "chainedcontext", + "extension", + "reversechainedcontextsingle", +} +local gpostypes={ + "single", + "pair", + "cursive", + "marktobase", + "marktoligature", + "marktomark", + "context", + "chainedcontext", + "extension", +} +local chaindirections={ + context=0, + chainedcontext=1, + reversechainedcontextsingle=-1, +} +local function setmetrics(data,where,tag,d) + local w=data[where] + if w then + local v=w[tag] + if v then + w[tag]=v+d + end + end +end +local variabletags={ + hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, + hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, + hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, + hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, + hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, + vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, + vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, + vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, + xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, + cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, + sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, + sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, + sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, + sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, + spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, + spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, + spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, + spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, + strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, + stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, + unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, + undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, +} +local read_cardinal={ + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, +} +local read_integer={ + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, +} +local lookupnames={ + gsub={ + single="gsub_single", + multiple="gsub_multiple", + alternate="gsub_alternate", + ligature="gsub_ligature", + context="gsub_context", + chainedcontext="gsub_contextchain", + reversechainedcontextsingle="gsub_reversecontextchain", + }, + gpos={ + single="gpos_single", + pair="gpos_pair", + cursive="gpos_cursive", + marktobase="gpos_mark2base", + marktoligature="gpos_mark2ligature", + marktomark="gpos_mark2mark", + context="gpos_context", + chainedcontext="gpos_contextchain", + } +} +local lookupflags=setmetatableindex(function(t,k) + local v={ + band(k,0x0008)~=0 and true or false, + band(k,0x0004)~=0 and true or false, + band(k,0x0002)~=0 and true or false, + band(k,0x0001)~=0 and true or false, + } + t[k]=v + return v +end) +local function axistofactors(str) + local t=settings_to_hash(str) + for k,v in next,t do + t[k]=tonumber(v) or v + end + return t +end +local hash=table.setmetatableindex(function(t,k) + local v=sequenced(axistofactors(k),",") + t[k]=v + return v +end) +helpers.normalizedaxishash=hash +local cleanname=fonts.names and fonts.names.cleanname or function(name) + return name and (gsub(lower(name),"[^%a%d]","")) or nil +end +helpers.cleanname=cleanname +function helpers.normalizedaxis(str) + return hash[str] or str +end +local function getaxisscale(segments,minimum,default,maximum,user) + if not minimum or not default or not maximum then + return false + end + if usermaximum then + user=maximum + end + if userdefault then + default=(user-default)/(maximum-default) + else + default=0 + end + if not segments then + return default + end + local e + for i=1,#segments do + local s=segments[i] + if type(s)~="number" then + report("using default axis scale") + return default + elseif s[1]>=default then + if s[2]==default then + return default + else + e=i + break + end + end + end + if e then + local b=segments[e-1] + local e=segments[e] + return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) + else + return false + end +end +local function getfactors(data,instancespec) + if instancespec==true then + elseif type(instancespec)~="string" or instancespec=="" then + return + end + local variabledata=data.variabledata + if not variabledata then + return + end + local instances=variabledata.instances + local axis=variabledata.axis + local segments=variabledata.segments + if instances and axis then + local values + if instancespec==true then + values={} + for i=1,#axis do + values[i]={ + value=axis[i].default, + } + end + else + for i=1,#instances do + local instance=instances[i] + if cleanname(instance.subfamily)==instancespec then + values=instance.values + break + end + end + end + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) + end + return factors + end + local values=axistofactors(hash[instancespec] or instancespec) + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + local d=a.default + factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + end + return factors + end + end +end +local function getscales(regions,factors) + local scales={} + for i=1,#regions do + local region=regions[i] + local s=1 + for j=1,#region do + local axis=region[j] + local f=factors[j] + local start=axis.start + local peak=axis.peak + local stop=axis.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + scales[i]=s + end + return scales +end +helpers.getaxisscale=getaxisscale +helpers.getfactors=getfactors +helpers.getscales=getscales +helpers.axistofactors=axistofactors +local function readvariationdata(f,storeoffset,factors) + local position=getposition(f) + setposition(f,storeoffset) + local format=readushort(f) + local regionoffset=storeoffset+readulong(f) + local nofdeltadata=readushort(f) + local deltadata=readcardinaltable(f,nofdeltadata,ulong) + setposition(f,regionoffset) + local nofaxis=readushort(f) + local nofregions=readushort(f) + local regions={} + for i=1,nofregions do + local t={} + for i=1,nofaxis do + t[i]={ + start=read2dot14(f), + peak=read2dot14(f), + stop=read2dot14(f), + } + end + regions[i]=t + end + if factors then + for i=1,nofdeltadata do + setposition(f,storeoffset+deltadata[i]) + local nofdeltasets=readushort(f) + local nofshorts=readushort(f) + local nofregions=readushort(f) + local usedregions={} + local deltas={} + for i=1,nofregions do + usedregions[i]=regions[readushort(f)+1] + end + for i=1,nofdeltasets do + local t=readintegertable(f,nofshorts,short) + for i=nofshorts+1,nofregions do + t[i]=readinteger(f) + end + deltas[i]=t + end + deltadata[i]={ + regions=usedregions, + deltas=deltas, + scales=factors and getscales(usedregions,factors) or nil, + } + end + end + setposition(f,position) + return regions,deltadata +end +helpers.readvariationdata=readvariationdata +local function readcoverage(f,offset,simple) + setposition(f,offset) + local coverageformat=readushort(f) + if coverageformat==1 then + local nofcoverage=readushort(f) + if simple then + if nofcoverage==1 then + return { readushort(f) } + elseif nofcoverage==2 then + return { readushort(f),readushort(f) } + else + return readcardinaltable(f,nofcoverage,ushort) + end + elseif nofcoverage==1 then + return { [readushort(f)]=0 } + elseif nofcoverage==2 then + return { [readushort(f)]=0,[readushort(f)]=1 } + else + local coverage={} + for i=0,nofcoverage-1 do + coverage[readushort(f)]=i + end + return coverage + end + elseif coverageformat==2 then + local nofranges=readushort(f) + local coverage={} + local n=simple and 1 or 0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local coverindex=readushort(f) + if simple then + for i=firstindex,lastindex do + coverage[n]=i + n=n+1 + end + else + for i=firstindex,lastindex do + coverage[i]=n + n=n+1 + end + end + end + return coverage + else + report("unknown coverage format %a ",coverageformat) + return {} + end +end +local function readclassdef(f,offset,preset) + setposition(f,offset) + local classdefformat=readushort(f) + local classdef={} + if type(preset)=="number" then + for k=0,preset-1 do + classdef[k]=1 + end + end + if classdefformat==1 then + local index=readushort(f) + local nofclassdef=readushort(f) + for i=1,nofclassdef do + classdef[index]=readushort(f)+1 + index=index+1 + end + elseif classdefformat==2 then + local nofranges=readushort(f) + local n=0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=readushort(f)+1 + for i=firstindex,lastindex do + classdef[i]=class + end + end + else + report("unknown classdef format %a ",classdefformat) + end + if type(preset)=="table" then + for k in next,preset do + if not classdef[k] then + classdef[k]=1 + end + end + end + return classdef +end +local function classtocoverage(defs) + if defs then + local list={} + for index,class in next,defs do + local c=list[class] + if c then + c[#c+1]=index + else + list[class]={ index } + end + end + return list + end +end +local skips={ [0]=0, + 1, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 2, + 3, + 2, + 3, + 3, + 4, +} +local function readvariation(f,offset) + local p=getposition(f) + setposition(f,offset) + local outer=readushort(f) + local inner=readushort(f) + local format=readushort(f) + setposition(f,p) + if format==0x8000 then + return outer,inner + end +end +local function readposition(f,format,mainoffset,getdelta) + if format==0 then + return false + end + if format==0x04 then + local h=readshort(f) + if h==0 then + return true + else + return { 0,0,h,0 } + end + end + if format==0x05 then + local x=readshort(f) + local h=readshort(f) + if x==0 and h==0 then + return true + else + return { x,0,h,0 } + end + end + if format==0x44 then + local h=readshort(f) + if getdelta then + local d=readshort(f) + if d>0 then + local outer,inner=readvariation(f,mainoffset+d) + if outer then + h=h+getdelta(outer,inner) + end + end + else + skipshort(f,1) + end + if h==0 then + return true + else + return { 0,0,h,0 } + end + end + local x=band(format,0x1)~=0 and readshort(f) or 0 + local y=band(format,0x2)~=0 and readshort(f) or 0 + local h=band(format,0x4)~=0 and readshort(f) or 0 + local v=band(format,0x8)~=0 and readshort(f) or 0 + if format>=0x10 then + local X=band(format,0x10)~=0 and skipshort(f) or 0 + local Y=band(format,0x20)~=0 and skipshort(f) or 0 + local H=band(format,0x40)~=0 and skipshort(f) or 0 + local V=band(format,0x80)~=0 and skipshort(f) or 0 + local s=skips[extract(format,4,4)] + if s>0 then + skipshort(f,s) + end + if getdelta then + if X>0 then + local outer,inner=readvariation(f,mainoffset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,mainoffset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + if H>0 then + local outer,inner=readvariation(f,mainoffset+H) + if outer then + h=h+getdelta(outer,inner) + end + end + if V>0 then + local outer,inner=readvariation(f,mainoffset+V) + if outer then + v=v+getdelta(outer,inner) + end + end + end + return { x,y,h,v } + elseif x==0 and y==0 and h==0 and v==0 then + return true + else + return { x,y,h,v } + end +end +local function readanchor(f,offset,getdelta) + if not offset or offset==0 then + return nil + end + setposition(f,offset) + local format=readshort(f) + local x=readshort(f) + local y=readshort(f) + if format==3 then + if getdelta then + local X=readshort(f) + local Y=readshort(f) + if X>0 then + local outer,inner=readvariation(f,offset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,offset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + else + skipshort(f,2) + end + return { x,y } + else + return { x,y } + end +end +local function readfirst(f,offset) + if offset then + setposition(f,offset) + end + return { readushort(f) } +end +local function readarray(f,offset) + if offset then + setposition(f,offset) + end + local n=readushort(f) + if n==1 then + return { readushort(f) },1 + elseif n>0 then + return readcardinaltable(f,n,ushort),n + end +end +local function readcoveragearray(f,offset,t,simple) + if not t then + return nil + end + local n=#t + if n==0 then + return nil + end + for i=1,n do + t[i]=readcoverage(f,offset+t[i],simple) + end + return t +end +local function covered(subset,all) + local used,u + for i=1,#subset do + local s=subset[i] + if all[s] then + if used then + u=u+1 + used[u]=s + else + u=1 + used={ s } + end + end + end + return used +end +local function readlookuparray(f,noflookups,nofcurrent) + local lookups={} + if noflookups>0 then + local length=0 + for i=1,noflookups do + local index=readushort(f)+1 + if index>length then + length=index + end + local lookup=readushort(f)+1 + local list=lookups[index] + if list then + list[#list+1]=lookup + else + lookups[index]={ lookup } + end + end + for index=1,length do + if not lookups[index] then + lookups[index]=false + end + end + end + return lookups +end +local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end + end + end + else + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local currentclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage) + currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end + else + report("no coverage") + end + else + report("no coverage class") + end + end + end + else + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local nofglyphs=readushort(f) + local noflookups=readushort(f) + local current=readcardinaltable(f,nofglyphs,ushort) + local lookups=readlookuparray(f,noflookups,#current) + current=readcoveragearray(f,tableoffset,current,true) + return { + format="coverage", + rules={ + { + current=current, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) + end +end +local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]={ readushort(f) } + end + end + local nofcurrent=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]={ readushort(f) } + end + end + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, + } + end + end + end + else + report("empty subclassset in %a subtype %i","chainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local beforeclassdef=readushort(f) + local currentclassdef=readushort(f) + local afterclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + local coverage=readcoverage(f,tableoffset+coverage) + local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) + local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) + local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]=beforeclasses[readushort(f)+1] + end + end + local nofcurrent=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]=afterclasses[readushort(f)+1] + end + end + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, + } + end + else + report("no coverage") + end + else + report("class is not covered") + end + end + end + else + report("empty subclassset in %a subtype %i","chainedcontext",subtype) + end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local before=readarray(f) + local current=readarray(f) + local after=readarray(f) + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,#current) + before=readcoveragearray(f,tableoffset,before,true) + current=readcoveragearray(f,tableoffset,current,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="coverage", + rules={ + { + before=before, + current=current, + after=after, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) + end +end +local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local lookuptype=types[readushort(f)] + local faroffset=readulong(f) + local handler=handlers[lookuptype] + if handler then + return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype + else + report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") + end + else + report("unsupported subtype %a in %s %s",subtype,what,"extension") + end +end +function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local delta=readshort(f) + local coverage=readcoverage(f,tableoffset+coverage) + for index in next,coverage do + local newindex=(index+delta)%65536 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=newindex + end + end + return { + coverage=coverage + } + elseif subtype==2 then + local coverage=readushort(f) + local nofreplacements=readushort(f) + local replacements=readcardinaltable(f,nofreplacements,ushort) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=replacements[newindex] + end + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"single") + end +end +local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsequence=readushort(f) + local sequences=readcardinaltable(f,nofsequence,ushort) + for i=1,nofsequence do + setposition(f,tableoffset+sequences[i]) + sequences[i]=readcardinaltable(f,readushort(f),ushort) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=sequences[newindex] + end + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,what) + end +end +function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") +end +function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") +end +function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsets=readushort(f) + local ligatures=readcardinaltable(f,nofsets,ushort) + for i=1,nofsets do + local offset=lookupoffset+offset+ligatures[i] + setposition(f,offset) + local n=readushort(f) + if n==1 then + ligatures[i]={ offset+readushort(f) } + else + local l={} + for i=1,n do + l[i]=offset+readushort(f) + end + ligatures[i]=l + end + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + local hash={} + local ligatures=ligatures[newindex+1] + for i=1,#ligatures do + local offset=ligatures[i] + setposition(f,offset) + local lig=readushort(f) + local cnt=readushort(f) + local hsh=hash + for i=2,cnt do + local c=readushort(f) + local h=hsh[c] + if not h then + h={} + hsh[c]=h + end + hsh=h + end + hsh.ligature=lig + end + coverage[index]=hash + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"ligature") + end +end +function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" +end +function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" +end +function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") +end +function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local current=readfirst(f) + local before=readarray(f) + local after=readarray(f) + local replacements=readarray(f) + current=readcoveragearray(f,tableoffset,current,true) + before=readcoveragearray(f,tableoffset,before,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="reversecoverage", + rules={ + { + before=before, + current=current, + after=after, + replacements=replacements, + } + } + },"reversechainedcontextsingle" + else + report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") + end +end +local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) + local done={} + for i=1,#sets do + local offset=sets[i] + local reused=done[offset] + if not reused then + offset=tableoffset+offset + setposition(f,offset) + local n=readushort(f) + reused={} + for i=1,n do + reused[i]={ + readushort(f), + readposition(f,format1,offset,getdelta), + readposition(f,format2,offset,getdelta), + } + end + done[offset]=reused + end + sets[i]=reused + end + return sets +end +local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) + local classlist1={} + for i=1,nofclasses1 do + local classlist2={} + classlist1[i]=classlist2 + for j=1,nofclasses2 do + local one=readposition(f,format1,mainoffset,getdelta) + local two=readposition(f,format2,mainoffset,getdelta) + if one or two then + classlist2[j]={ one,two } + else + classlist2[j]=false + end + end + end + return classlist1 +end +function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format=readushort(f) + local value=readposition(f,format,tableoffset,getdelta) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=value + end + return { + format="single", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format=readushort(f) + local nofvalues=readushort(f) + local values={} + for i=1,nofvalues do + values[i]=readposition(f,format,tableoffset,getdelta) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=values[newindex+1] + end + return { + format="single", + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"single") + end +end +function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local sets=readarray(f) + sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + local shared={} + for index,newindex in next,coverage do + local set=sets[newindex+1] + local hash={} + for i=1,#set do + local value=set[i] + if value then + local other=value[1] + local share=shared[value] + if share==nil then + local first=value[2] + local second=value[3] + if first or second then + share={ first,second or nil } + else + share=false + end + shared[value]=share + end + hash[other]=share or nil + end + end + coverage[index]=hash + end + return { + shared=shared and true or nil, + format="pair", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local classdef1=readushort(f) + local classdef2=readushort(f) + local nofclasses1=readushort(f) + local nofclasses2=readushort(f) + local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + classdef1=readclassdef(f,tableoffset+classdef1,coverage) + classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) + local usedcoverage={} + local shared={} + for g1,c1 in next,classdef1 do + if coverage[g1] then + local l1=classlist[c1] + if l1 then + local hash={} + for paired,class in next,classdef2 do + local offsets=l1[class] + if offsets then + local first=offsets[1] + local second=offsets[2] + if first or second then + local s1=shared[first] + if s1==nil then + s1={} + shared[first]=s1 + end + local s2=s1[second] + if s2==nil then + s2={ first,second or nil } + s1[second]=s2 + end + hash[paired]=s2 + end + end + end + usedcoverage[g1]=hash + end + end + end + return { + shared=shared and true or nil, + format="pair", + coverage=usedcoverage, + } + elseif subtype==3 then + report("yet unsupported subtype %a in %a positioning",subtype,"pair") + else + report("unsupported subtype %a in %a positioning",subtype,"pair") + end +end +function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=tableoffset+readushort(f) + local nofrecords=readushort(f) + local records={} + for i=1,nofrecords do + local entry=readushort(f) + local exit=readushort(f) + records[i]={ + entry~=0 and (tableoffset+entry) or false, + exit~=0 and (tableoffset+exit ) or nil, + } + end + local cc=(fontdata.temporary.cursivecount or 0)+1 + fontdata.temporary.cursivecount=cc + cc="cc-"..cc + coverage=readcoverage(f,coverage) + for i=1,nofrecords do + local r=records[i] + records[i]={ + cc, + readanchor(f,r[1],getdelta) or false, + readanchor(f,r[2],getdelta) or nil, + } + end + for index,newindex in next,coverage do + coverage[index]=records[newindex+1] + end + return { + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"cursive") + end +end +local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local markcoverage=tableoffset+readushort(f) + local basecoverage=tableoffset+readushort(f) + local nofclasses=readushort(f) + local markoffset=tableoffset+readushort(f) + local baseoffset=tableoffset+readushort(f) + local markcoverage=readcoverage(f,markcoverage) + local basecoverage=readcoverage(f,basecoverage,true) + setposition(f,markoffset) + local markclasses={} + local nofmarkclasses=readushort(f) + local lastanchor=fontdata.lastanchor or 0 + local usedanchors={} + for i=1,nofmarkclasses do + local class=readushort(f)+1 + local offset=readushort(f) + if offset==0 then + markclasses[i]=false + else + markclasses[i]={ class,markoffset+offset } + end + usedanchors[class]=true + end + for i=1,nofmarkclasses do + local mc=markclasses[i] + if mc then + mc[2]=readanchor(f,mc[2],getdelta) + end + end + setposition(f,baseoffset) + local nofbaserecords=readushort(f) + local baserecords={} + if ligature then + for i=1,nofbaserecords do + local offset=readushort(f) + if offset==0 then + baserecords[i]=false + else + baserecords[i]=baseoffset+offset + end + end + for i=1,nofbaserecords do + local recordoffset=baserecords[i] + if recordoffset then + setposition(f,recordoffset) + local nofcomponents=readushort(f) + local components={} + for i=1,nofcomponents do + local classes={} + for i=1,nofclasses do + local offset=readushort(f) + if offset~=0 then + classes[i]=recordoffset+offset + else + classes[i]=false + end + end + components[i]=classes + end + baserecords[i]=components + end + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local components=baserecords[i] + if components then + local b=basecoverage[i] + for c=1,#components do + local classes=components[c] + if classes then + for i=1,nofclasses do + local anchor=readanchor(f,classes[i],getdelta) + local bclass=baseclasses[i] + local bentry=bclass[b] + if bentry then + bentry[c]=anchor + else + bclass[b]={ [c]=anchor } + end + end + end + end + end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="ligature", + baseclasses=baseclasses, + coverage=markcoverage, + } + else + for i=1,nofbaserecords do + local r={} + for j=1,nofclasses do + local offset=readushort(f) + if offset==0 then + r[j]=false + else + r[j]=baseoffset+offset + end + end + baserecords[i]=r + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local r=baserecords[i] + local b=basecoverage[i] + for j=1,nofclasses do + baseclasses[j][b]=readanchor(f,r[j],getdelta) + end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="base", + baseclasses=baseclasses, + coverage=markcoverage, + } + end + else + report("unsupported subtype %a in",subtype) + end +end +function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) +end +function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) +end +function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) +end +function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" +end +function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" +end +function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") +end +do + local plugins={} + function plugins.size(f,fontdata,tableoffset,feature) + if fontdata.designsize then + else + local function check(offset) + setposition(f,offset) + local designsize=readushort(f) + if designsize>0 then + local fontstyleid=readushort(f) + local guimenuid=readushort(f) + local minsize=readushort(f) + local maxsize=readushort(f) + if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then + minsize=designsize + maxsize=designsize + end + if designsize>=minsize and designsize<=maxsize then + return minsize,maxsize,designsize + end + end + end + local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) + if not designsize then + minsize,maxsize,designsize=check(tableoffset+feature.parameters) + if designsize then + report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") + else + report("bad size feature in %a,",fontdata.filename or "?") + end + end + if designsize then + fontdata.minsize=minsize + fontdata.maxsize=maxsize + fontdata.designsize=designsize + end + end + end + local function reorderfeatures(fontdata,scripts,features) + local scriptlangs={} + local featurehash={} + local featureorder={} + for script,languages in next,scripts do + for language,record in next,languages do + local hash={} + local list=record.featureindices + for k=1,#list do + local index=list[k] + local feature=features[index] + local lookups=feature.lookups + local tag=feature.tag + if tag then + hash[tag]=true + end + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local o=featureorder[lookup] + if o then + local okay=true + for i=1,#o do + if o[i]==tag then + okay=false + break + end + end + if okay then + o[#o+1]=tag + end + else + featureorder[lookup]={ tag } + end + local f=featurehash[lookup] + if f then + local h=f[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } + end + else + f[tag]={ [script]={ [language]=true } } + end + else + featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } + end + local h=scriptlangs[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } + end + else + scriptlangs[tag]={ [script]={ [language]=true } } + end + end + end + end + end + end + return scriptlangs,featurehash,featureorder + end + local function readscriplan(f,fontdata,scriptoffset) + setposition(f,scriptoffset) + local nofscripts=readushort(f) + local scripts={} + for i=1,nofscripts do + scripts[readtag(f)]=scriptoffset+readushort(f) + end + local languagesystems=setmetatableindex("table") + for script,offset in next,scripts do + setposition(f,offset) + local defaultoffset=readushort(f) + local noflanguages=readushort(f) + local languages={} + if defaultoffset>0 then + languages.dflt=languagesystems[offset+defaultoffset] + end + for i=1,noflanguages do + local language=readtag(f) + local offset=offset+readushort(f) + languages[language]=languagesystems[offset] + end + scripts[script]=languages + end + for offset,usedfeatures in next,languagesystems do + if offset>0 then + setposition(f,offset) + local featureindices={} + usedfeatures.featureindices=featureindices + usedfeatures.lookuporder=readushort(f) + usedfeatures.requiredindex=readushort(f) + local noffeatures=readushort(f) + for i=1,noffeatures do + featureindices[i]=readushort(f)+1 + end + end + end + return scripts + end + local function readfeatures(f,fontdata,featureoffset) + setposition(f,featureoffset) + local features={} + local noffeatures=readushort(f) + for i=1,noffeatures do + features[i]={ + tag=readtag(f), + offset=readushort(f) + } + end + for i=1,noffeatures do + local feature=features[i] + local offset=featureoffset+feature.offset + setposition(f,offset) + local parameters=readushort(f) + local noflookups=readushort(f) + if noflookups>0 then + local lookups=readcardinaltable(f,noflookups,ushort) + feature.lookups=lookups + for j=1,noflookups do + lookups[j]=lookups[j]+1 + end + end + if parameters>0 then + feature.parameters=parameters + local plugin=plugins[feature.tag] + if plugin then + plugin(f,fontdata,featureoffset,feature) + end + end + end + return features + end + local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + setposition(f,lookupoffset) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + for lookupid=1,noflookups do + local offset=lookups[lookupid] + setposition(f,lookupoffset+offset) + local subtables={} + local typebits=readushort(f) + local flagbits=readushort(f) + local lookuptype=lookuptypes[typebits] + local lookupflags=lookupflags[flagbits] + local nofsubtables=readushort(f) + for j=1,nofsubtables do + subtables[j]=offset+readushort(f) + end + local markclass=band(flagbits,0x0010)~=0 + if markclass then + markclass=readushort(f) + end + local markset=rshift(flagbits,8) + if markset>0 then + markclass=markset + end + lookups[lookupid]={ + type=lookuptype, + flags=lookupflags, + name=lookupid, + subtables=subtables, + markclass=markclass, + features=featurehash[lookupid], + order=featureorder[lookupid], + } + end + return lookups + end + local f_lookupname=formatters["%s_%s_%s"] + local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + local sequences=fontdata.sequences or {} + local sublookuplist=fontdata.sublookups or {} + fontdata.sequences=sequences + fontdata.sublookups=sublookuplist + local nofsublookups=#sublookuplist + local nofsequences=#sequences + local lastsublookup=nofsublookups + local lastsequence=nofsequences + local lookupnames=lookupnames[what] + local sublookuphash={} + local sublookupcheck={} + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs or #glyphs + local noflookups=#lookups + local lookupprefix=sub(what,2,2) + local usedlookups=false + for lookupid=1,noflookups do + local lookup=lookups[lookupid] + local lookuptype=lookup.type + local subtables=lookup.subtables + local features=lookup.features + local handler=lookuphandlers[lookuptype] + if handler then + local nofsubtables=#subtables + local order=lookup.order + local flags=lookup.flags + if flags[1] then flags[1]="mark" end + if flags[2] then flags[2]="ligature" end + if flags[3] then flags[3]="base" end + local markclass=lookup.markclass + if nofsubtables>0 then + local steps={} + local nofsteps=0 + local oldtype=nil + for s=1,nofsubtables do + local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) + if lt then + lookuptype=lt + if oldtype and lt~=oldtype then + report("messy %s lookup type %a and %a",what,lookuptype,oldtype) + end + oldtype=lookuptype + end + if not step then + report("unsupported %s lookup type %a",what,lookuptype) + else + nofsteps=nofsteps+1 + steps[nofsteps]=step + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + local current=rule.current + local after=rule.after + local replacements=rule.replacements + if before then + for i=1,#before do + before[i]=tohash(before[i]) + end + rule.before=reversed(before) + end + if current then + if replacements then + local first=current[1] + local hash={} + local repl={} + for i=1,#first do + local c=first[i] + hash[c]=true + repl[c]=replacements[i] + end + rule.current={ hash } + rule.replacements=repl + else + for i=1,#current do + current[i]=tohash(current[i]) + end + end + else + end + if after then + for i=1,#after do + after[i]=tohash(after[i]) + end + end + if usedlookups then + local lookups=rule.lookups + if lookups then + for k,v in next,lookups do + if v then + for k,v in next,v do + usedlookups[v]=usedlookups[v]+1 + end + end + end + end + end + end + end + end + end + if nofsteps~=nofsubtables then + report("bogus subtables removed in %s lookup type %a",what,lookuptype) + end + lookuptype=lookupnames[lookuptype] or lookuptype + if features then + nofsequences=nofsequences+1 + local l={ + index=nofsequences, + name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + order=order, + features=features, + } + sequences[nofsequences]=l + lookup.done=l + else + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + } + sublookuplist[nofsublookups]=l + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=0 + lookup.done=l + end + else + report("no subtables for lookup %a",lookupid) + end + else + report("no handler for lookup %a with type %a",lookupid,lookuptype) + end + end + if usedlookups then + report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end + local reported={} + local function report_issue(i,what,sequence,kind) + local name=sequence.name + if not reported[name] then + report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) + reported[name]=true + end + end + for i=lastsequence+1,nofsequences do + local sequence=sequences[i] + local steps=sequence.steps + for i=1,#steps do + local step=steps[i] + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local rlookups=rule.lookups + if not rlookups then + report_issue(i,what,sequence,"no") + elseif not next(rlookups) then + rule.lookups=nil + else + local length=#rlookups + for index=1,length do + local lookuplist=rlookups[index] + if lookuplist then + local length=#lookuplist + local found={} + local noffound=0 + for index=1,length do + local lookupid=lookuplist[index] + if lookupid then + local h=sublookuphash[lookupid] + if not h then + local lookup=lookups[lookupid] + if lookup then + local d=lookup.done + if d then + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), + derived=true, + steps=d.steps, + nofsteps=d.nofsteps, + type=d.lookuptype or "gsub_single", + markclass=d.markclass or nil, + flags=d.flags, + } + sublookuplist[nofsublookups]=copy(l) + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=1 + h=nofsublookups + else + report_issue(i,what,sequence,"missing") + rule.lookups=nil + break + end + else + report_issue(i,what,sequence,"bad") + rule.lookups=nil + break + end + else + sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 + end + if h then + noffound=noffound+1 + found[noffound]=h + end + end + end + rlookups[index]=noffound>0 and found or false + else + rlookups[index]=false + end + end + end + end + end + end + end + for i,n in sortedhash(sublookupcheck) do + local l=lookups[i] + local t=l.type + if n==0 and t~="extension" then + local d=l.done + report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) + end + end + end + local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + setposition(f,variationsoffset) + local version=readulong(f) + local nofrecords=readulong(f) + local records={} + for i=1,nofrecords do + records[i]={ + conditions=readulong(f), + substitutions=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local offset=record.conditions + if offset==0 then + record.condition=nil + record.matchtype="always" + else + local offset=variationsoffset+offset + setposition(f,offset) + local nofconditions=readushort(f) + local conditions={} + for i=1,nofconditions do + conditions[i]=offset+readulong(f) + end + record.conditions=conditions + record.matchtype="condition" + end + end + for i=1,nofrecords do + local record=records[i] + if record.matchtype=="condition" then + local conditions=record.conditions + for i=1,#conditions do + setposition(f,conditions[i]) + conditions[i]={ + format=readushort(f), + axis=readushort(f), + minvalue=read2dot14(f), + maxvalue=read2dot14(f), + } + end + end + end + for i=1,nofrecords do + local record=records[i] + local offset=record.substitutions + if offset==0 then + record.substitutions={} + else + setposition(f,variationsoffset+offset) + local version=readulong(f) + local nofsubstitutions=readushort(f) + local substitutions={} + for i=1,nofsubstitutions do + substitutions[readushort(f)]=readulong(f) + end + for index,alternates in sortedhash(substitutions) do + if index==0 then + record.substitutions=false + else + local tableoffset=variationsoffset+offset+alternates + setposition(f,tableoffset) + local parameters=readulong(f) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + record.substitutions=lookups + end + end + end + end + setvariabledata(fontdata,"features",records) + end + local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) + local tableoffset=gotodatatable(f,fontdata,what,true) + if tableoffset then + local version=readulong(f) + local scriptoffset=tableoffset+readushort(f) + local featureoffset=tableoffset+readushort(f) + local lookupoffset=tableoffset+readushort(f) + local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 + if not scriptoffset then + return + end + local scripts=readscriplan(f,fontdata,scriptoffset) + local features=readfeatures(f,fontdata,featureoffset) + local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) + if fontdata.features then + fontdata.features[what]=scriptlangs + else + fontdata.features={ [what]=scriptlangs } + end + if not lookupstoo then + return + end + local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + if lookups then + resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + end + if variationsoffset>0 then + loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + end + end + end + local function checkkerns(f,fontdata,specification) + local datatable=fontdata.tables.kern + if not datatable then + return + end + local features=fontdata.features + local gposfeatures=features and features.gpos + local name + if not gposfeatures or not gposfeatures.kern then + name="kern" + elseif specification.globalkerns then + name="globalkern" + else + report("ignoring global kern table, using gpos kern feature") + return + end + setposition(f,datatable.offset) + local version=readushort(f) + local noftables=readushort(f) + if noftables>1 then + report("adding global kern table as gpos feature %a",name) + local kerns=setmetatableindex("table") + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)]=readfword(f) + end + elseif format==2 then + else + end + end + local feature={ dflt={ dflt=true } } + if not features then + fontdata.features={ gpos={ [name]=feature } } + elseif not gposfeatures then + fontdata.features.gpos={ [name]=feature } + else + gposfeatures[name]=feature + end + local sequences=fontdata.sequences + if not sequences then + sequences={} + fontdata.sequences=sequences + end + local nofsequences=#sequences+1 + sequences[nofsequences]={ + index=nofsequences, + name=name, + steps={ + { + coverage=kerns, + format="kern", + }, + }, + nofsteps=1, + type="gpos_pair", + flags={ false,false,false,false }, + order={ name }, + features={ [name]=feature }, + } + else + report("ignoring empty kern table of feature %a",name) + end + end + function readers.gsub(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) + end + end + function readers.gpos(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) + if specification.lookups then + checkkerns(f,fontdata,specification) + end + end + end +end +function readers.gdef(f,fontdata,specification) + if not specification.glyphs then + return + end + local datatable=fontdata.tables.gdef + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + local version=readulong(f) + local classoffset=readushort(f) + local attachmentoffset=readushort(f) + local ligaturecarets=readushort(f) + local markclassoffset=readushort(f) + local marksetsoffset=version>=0x00010002 and readushort(f) or 0 + local varsetsoffset=version>=0x00010003 and readulong(f) or 0 + local glyphs=fontdata.glyphs + local marks={} + local markclasses=setmetatableindex("table") + local marksets=setmetatableindex("table") + fontdata.marks=marks + fontdata.markclasses=markclasses + fontdata.marksets=marksets + if classoffset~=0 then + setposition(f,tableoffset+classoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + local class=classes[readushort(f)] + if class=="mark" then + marks[index]=true + end + glyphs[index].class=class + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class=class + if class=="mark" then + marks[index]=true + end + end + end + end + end + end + if markclassoffset~=0 then + setposition(f,tableoffset+markclassoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + markclasses[readushort(f)][index]=true + end + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=markclasses[readushort(f)] + for index=firstindex,lastindex do + class[index]=true + end + end + end + end + if marksetsoffset~=0 then + marksetsoffset=tableoffset+marksetsoffset + setposition(f,marksetsoffset) + local format=readushort(f) + if format==1 then + local nofsets=readushort(f) + local sets=readcardinaltable(f,nofsets,ulong) + for i=1,nofsets do + local offset=sets[i] + if offset~=0 then + marksets[i]=readcoverage(f,marksetsoffset+offset) + end + end + end + end + local factors=specification.factors + if (specification.variable or factors) and varsetsoffset~=0 then + local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) + if factors then + fontdata.temporary.getdelta=function(outer,inner) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + local di=d[i] + if di then + dd=dd+scales[i]*di + else + break + end + end + return round(dd) + end + end + return 0 + end + end + end + end +end +local function readmathvalue(f) + local v=readshort(f) + skipshort(f,1) + return v +end +local function readmathconstants(f,fontdata,offset) + setposition(f,offset) + fontdata.mathconstants={ + ScriptPercentScaleDown=readshort(f), + ScriptScriptPercentScaleDown=readshort(f), + DelimitedSubFormulaMinHeight=readushort(f), + DisplayOperatorMinHeight=readushort(f), + MathLeading=readmathvalue(f), + AxisHeight=readmathvalue(f), + AccentBaseHeight=readmathvalue(f), + FlattenedAccentBaseHeight=readmathvalue(f), + SubscriptShiftDown=readmathvalue(f), + SubscriptTopMax=readmathvalue(f), + SubscriptBaselineDropMin=readmathvalue(f), + SuperscriptShiftUp=readmathvalue(f), + SuperscriptShiftUpCramped=readmathvalue(f), + SuperscriptBottomMin=readmathvalue(f), + SuperscriptBaselineDropMax=readmathvalue(f), + SubSuperscriptGapMin=readmathvalue(f), + SuperscriptBottomMaxWithSubscript=readmathvalue(f), + SpaceAfterScript=readmathvalue(f), + UpperLimitGapMin=readmathvalue(f), + UpperLimitBaselineRiseMin=readmathvalue(f), + LowerLimitGapMin=readmathvalue(f), + LowerLimitBaselineDropMin=readmathvalue(f), + StackTopShiftUp=readmathvalue(f), + StackTopDisplayStyleShiftUp=readmathvalue(f), + StackBottomShiftDown=readmathvalue(f), + StackBottomDisplayStyleShiftDown=readmathvalue(f), + StackGapMin=readmathvalue(f), + StackDisplayStyleGapMin=readmathvalue(f), + StretchStackTopShiftUp=readmathvalue(f), + StretchStackBottomShiftDown=readmathvalue(f), + StretchStackGapAboveMin=readmathvalue(f), + StretchStackGapBelowMin=readmathvalue(f), + FractionNumeratorShiftUp=readmathvalue(f), + FractionNumeratorDisplayStyleShiftUp=readmathvalue(f), + FractionDenominatorShiftDown=readmathvalue(f), + FractionDenominatorDisplayStyleShiftDown=readmathvalue(f), + FractionNumeratorGapMin=readmathvalue(f), + FractionNumeratorDisplayStyleGapMin=readmathvalue(f), + FractionRuleThickness=readmathvalue(f), + FractionDenominatorGapMin=readmathvalue(f), + FractionDenominatorDisplayStyleGapMin=readmathvalue(f), + SkewedFractionHorizontalGap=readmathvalue(f), + SkewedFractionVerticalGap=readmathvalue(f), + OverbarVerticalGap=readmathvalue(f), + OverbarRuleThickness=readmathvalue(f), + OverbarExtraAscender=readmathvalue(f), + UnderbarVerticalGap=readmathvalue(f), + UnderbarRuleThickness=readmathvalue(f), + UnderbarExtraDescender=readmathvalue(f), + RadicalVerticalGap=readmathvalue(f), + RadicalDisplayStyleVerticalGap=readmathvalue(f), + RadicalRuleThickness=readmathvalue(f), + RadicalExtraAscender=readmathvalue(f), + RadicalKernBeforeDegree=readmathvalue(f), + RadicalKernAfterDegree=readmathvalue(f), + RadicalDegreeBottomRaisePercent=readshort(f), + } +end +local function readmathglyphinfo(f,fontdata,offset) + setposition(f,offset) + local italics=readushort(f) + local accents=readushort(f) + local extensions=readushort(f) + local kerns=readushort(f) + local glyphs=fontdata.glyphs + if italics~=0 then + setposition(f,offset+italics) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+italics+coverage,true) + setposition(f,offset+italics+4) + for i=1,nofglyphs do + local italic=readmathvalue(f) + if italic~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ italic=italic } + else + math.italic=italic + end + end + end + fontdata.hasitalics=true + end + if accents~=0 then + setposition(f,offset+accents) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+accents+coverage,true) + setposition(f,offset+accents+4) + for i=1,nofglyphs do + local accent=readmathvalue(f) + if accent~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ accent=accent } + else + math.accent=accent + end + end + end + end + if extensions~=0 then + setposition(f,offset+extensions) + end + if kerns~=0 then + local kernoffset=offset+kerns + setposition(f,kernoffset) + local coverage=readushort(f) + local nofglyphs=readushort(f) + if nofglyphs>0 then + local function get(offset) + setposition(f,kernoffset+offset) + local n=readushort(f) + if n==0 then + local k=readmathvalue(f) + if k==0 then + else + return { { kern=k } } + end + else + local l={} + for i=1,n do + l[i]={ height=readmathvalue(f) } + end + for i=1,n do + l[i].kern=readmathvalue(f) + end + l[n+1]={ kern=readmathvalue(f) } + return l + end + end + local kernsets={} + for i=1,nofglyphs do + local topright=readushort(f) + local topleft=readushort(f) + local bottomright=readushort(f) + local bottomleft=readushort(f) + kernsets[i]={ + topright=topright~=0 and topright or nil, + topleft=topleft~=0 and topleft or nil, + bottomright=bottomright~=0 and bottomright or nil, + bottomleft=bottomleft~=0 and bottomleft or nil, + } + end + coverage=readcoverage(f,kernoffset+coverage,true) + for i=1,nofglyphs do + local kernset=kernsets[i] + if next(kernset) then + local k=kernset.topright if k then kernset.topright=get(k) end + local k=kernset.topleft if k then kernset.topleft=get(k) end + local k=kernset.bottomright if k then kernset.bottomright=get(k) end + local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end + if next(kernset) then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if math then + math.kerns=kernset + else + glyph.math={ kerns=kernset } + end + end + end + end + end + end +end +local function readmathvariants(f,fontdata,offset) + setposition(f,offset) + local glyphs=fontdata.glyphs + local minoverlap=readushort(f) + local vcoverage=readushort(f) + local hcoverage=readushort(f) + local vnofglyphs=readushort(f) + local hnofglyphs=readushort(f) + local vconstruction=readcardinaltable(f,vnofglyphs,ushort) + local hconstruction=readcardinaltable(f,hnofglyphs,ushort) + fontdata.mathconstants.MinConnectorOverlap=minoverlap + local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) + if coverage~=0 and nofglyphs>0 then + local coverage=readcoverage(f,offset+coverage,true) + for i=1,nofglyphs do + local c=construction[i] + if c~=0 then + local index=coverage[i] + local glyph=glyphs[index] + local math=glyph.math + setposition(f,offset+c) + local assembly=readushort(f) + local nofvariants=readushort(f) + if nofvariants>0 then + local variants,v=nil,0 + for i=1,nofvariants do + local variant=readushort(f) + if variant==index then + elseif variants then + v=v+1 + variants[v]=variant + else + v=1 + variants={ variant } + end + skipshort(f) + end + if not variants then + elseif not math then + math={ [kvariants]=variants } + glyph.math=math + else + math[kvariants]=variants + end + end + if assembly~=0 then + setposition(f,offset+c+assembly) + local italic=readmathvalue(f) + local nofparts=readushort(f) + local parts={} + for i=1,nofparts do + local p={ + glyph=readushort(f), + start=readushort(f), + ["end"]=readushort(f), + advance=readushort(f), + } + local flags=readushort(f) + if band(flags,0x0001)~=0 then + p.extender=1 + end + parts[i]=p + end + if not math then + math={ + [kparts]=parts + } + glyph.math=math + else + math[kparts]=parts + end + if italic and italic~=0 then + math[kitalic]=italic + end + end + end + end + end + end + get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") + get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") +end +function readers.math(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) + if tableoffset then + local version=readulong(f) + local constants=readushort(f) + local glyphinfo=readushort(f) + local variants=readushort(f) + if constants==0 then + report("the math table of %a has no constants",fontdata.filename) + else + readmathconstants(f,fontdata,tableoffset+constants) + end + if glyphinfo~=0 then + readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) + end + if variants~=0 then + readmathvariants(f,fontdata,tableoffset+variants) + end + end +end +function readers.colr(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) + if tableoffset then + local version=readushort(f) + if version~=0 then + report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) + return + end + if not fontdata.tables.cpal then + report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") + fontdata.colorpalettes={} + end + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local baseoffset=readulong(f) + local layeroffset=readulong(f) + local noflayers=readushort(f) + local layerrecords={} + local maxclass=0 + setposition(f,tableoffset+layeroffset) + for i=1,noflayers do + local slot=readushort(f) + local class=readushort(f) + if class<0xFFFF then + class=class+1 + if class>maxclass then + maxclass=class + end + end + layerrecords[i]={ + slot=slot, + class=class, + } + end + fontdata.maxcolorclass=maxclass + setposition(f,tableoffset+baseoffset) + for i=0,nofglyphs-1 do + local glyphindex=readushort(f) + local firstlayer=readushort(f) + local noflayers=readushort(f) + local t={} + for i=1,noflayers do + t[i]=layerrecords[firstlayer+i] + end + glyphs[glyphindex].colors=t + end + end + fontdata.hascolor=true +end +function readers.cpal(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) + if tableoffset then + local version=readushort(f) + local nofpaletteentries=readushort(f) + local nofpalettes=readushort(f) + local nofcolorrecords=readushort(f) + local firstcoloroffset=readulong(f) + local colorrecords={} + local palettes=readcardinaltable(f,nofpalettes,ushort) + if version==1 then + local palettettypesoffset=readulong(f) + local palettelabelsoffset=readulong(f) + local paletteentryoffset=readulong(f) + end + setposition(f,tableoffset+firstcoloroffset) + for i=1,nofcolorrecords do + local b,g,r,a=readbytes(f,4) + colorrecords[i]={ + r,g,b,a~=255 and a or nil, + } + end + for i=1,nofpalettes do + local p={} + local o=palettes[i] + for j=1,nofpaletteentries do + p[j]=colorrecords[o+j] + end + palettes[i]=p + end + fontdata.colorpalettes=palettes + end +end +local compress=gzip and gzip.compress +local compressed=compress and gzip.compressed +function readers.svg(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) + if tableoffset then + local version=readushort(f) + local glyphs=fontdata.glyphs + local indexoffset=tableoffset+readulong(f) + local reserved=readulong(f) + setposition(f,indexoffset) + local nofentries=readushort(f) + local entries={} + for i=1,nofentries do + entries[i]={ + first=readushort(f), + last=readushort(f), + offset=indexoffset+readulong(f), + length=readulong(f), + } + end + for i=1,nofentries do + local entry=entries[i] + setposition(f,entry.offset) + local data=readstring(f,entry.length) + if compressed and not compressed(data) then + data=compress(data) + end + entries[i]={ + first=entry.first, + last=entry.last, + data=data + } + end + fontdata.svgshapes=entries + end + fontdata.hascolor=true +end +function readers.sbix(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) + if tableoffset then + local version=readushort(f) + local flags=readushort(f) + local nofstrikes=readulong(f) + local strikes={} + local nofglyphs=fontdata.nofglyphs + for i=1,nofstrikes do + strikes[i]=readulong(f) + end + local shapes={} + local done=0 + for i=1,nofstrikes do + local strikeoffset=strikes[i]+tableoffset + setposition(f,strikeoffset) + strikes[i]={ + ppem=readushort(f), + ppi=readushort(f), + offset=strikeoffset + } + end + sort(strikes,function(a,b) + if b.ppem==a.ppem then + return b.ppi0 or fonts.handlers.typethree + for i=1,nofstrikes do + local strike=strikes[i] + local strikeppem=strike.ppem + local strikeppi=strike.ppi + local strikeoffset=strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i]=readulong(f) + end + local glyphoffset=glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset=glyphs[i+1] + if not shapes[i] then + local datasize=nextoffset-glyphoffset + if datasize>0 then + setposition(f,strikeoffset+glyphoffset) + local x=readshort(f) + local y=readshort(f) + local tag=readtag(f) + local size=datasize-8 + local data=nil + local offset=nil + if delayed then + offset=getposition(f) + data=nil + else + data=readstring(f,size) + size=nil + end + shapes[i]={ + x=x, + y=y, + o=offset, + s=size, + data=data, + } + done=done+1 + if done==nofglyphs then + break + end + end + end + glyphoffset=nextoffset + end + end + fontdata.pngshapes=shapes + end +end +do + local function getmetrics(f) + return { + ascender=readinteger(f), + descender=readinteger(f), + widthmax=readuinteger(f), + caretslopedumerator=readinteger(f), + caretslopedenominator=readinteger(f), + caretoffset=readinteger(f), + minorigin=readinteger(f), + minadvance=readinteger(f), + maxbefore=readinteger(f), + minafter=readinteger(f), + pad1=readinteger(f), + pad2=readinteger(f), + } + end + local function getbigmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + horiBearingX=readinteger(f), + horiBearingY=readinteger(f), + horiAdvance=readuinteger(f), + vertBearingX=readinteger(f), + vertBearingY=readinteger(f), + vertAdvance=readuinteger(f), + } + end + local function getsmallmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + bearingX=readinteger(f), + bearingY=readinteger(f), + advance=readuinteger(f), + } + end + function readers.cblc(f,fontdata,specification) + local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion=readushort(f) + local minorversion=readushort(f) + local nofsizetables=readulong(f) + local sizetables={} + local shapes={} + local subtables={} + for i=1,nofsizetables do + sizetables[i]={ + subtables=readulong(f), + indexsize=readulong(f), + nofsubtables=readulong(f), + colorref=readulong(f), + hormetrics=getmetrics(f), + vermetrics=getmetrics(f), + firstindex=readushort(f), + lastindex=readushort(f), + ppemx=readbyte(f), + ppemy=readbyte(f), + bitdepth=readbyte(f), + flags=readbyte(f), + } + end + sort(sizetables,function(a,b) + if b.ppemx==a.ppemx then + return b.bitdepth0 or fonts.handlers.typethree + for index,subtable in sortedhash(shapes) do + if type(subtable)=="table" then + local data=nil + local size=nil + local metrics=default + local format=subtable.format + local offset=subtable.offsets[index] + setposition(f,offset) + if format==17 then + metrics=getsmallmetrics(f) + size=true + elseif format==18 then + metrics=getbigmetrics(f) + size=true + elseif format==19 then + metrics=subtable.metrics + size=true + else + end + if size then + size=readulong(f) + if delayed then + offset=getposition(f) + data=nil + else + offset=nil + data=readstring(f,size) + size=nil + end + else + offset=nil + end + local x=metrics.width + local y=metrics.height + shapes[index]={ + x=x, + y=y, + o=offset, + s=size, + data=data, + } + local glyph=glyphs[index] + if not glyph.boundingbox then + local width=glyph.width + local height=width*y/x + glyph.boundingbox={ 0,0,width,height } + end + else + shapes[index]={ + x=0, + y=0, + data="", + } + end + end + fontdata.pngshapes=shapes + end + end + function readers.cbdt(f,fontdata,specification) + end +end +function readers.stat(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"stat",true) + if tableoffset then + local extras=fontdata.extras + local version=readulong(f) + local axissize=readushort(f) + local nofaxis=readushort(f) + local axisoffset=readulong(f) + local nofvalues=readushort(f) + local valuesoffset=readulong(f) + local fallbackname=extras[readushort(f)] + local axis={} + local values={} + setposition(f,tableoffset+axisoffset) + for i=1,nofaxis do + local tag=readtag(f) + axis[i]={ + tag=tag, + name=lower(extras[readushort(f)] or tag), + ordering=readushort(f), + variants={} + } + end + setposition(f,tableoffset+valuesoffset) + for i=1,nofvalues do + values[i]=readushort(f) + end + for i=1,nofvalues do + setposition(f,tableoffset+valuesoffset+values[i]) + local format=readushort(f) + local index=readushort(f)+1 + local flags=readushort(f) + local name=lower(extras[readushort(f)] or "no name") + local value=readfixed(f) + local variant + if format==1 then + variant={ + flags=flags, + name=name, + value=value, + } + elseif format==2 then + variant={ + flags=flags, + name=name, + value=value, + minimum=readfixed(f), + maximum=readfixed(f), + } + elseif format==3 then + variant={ + flags=flags, + name=name, + value=value, + link=readfixed(f), + } + end + insert(axis[index].variants,variant) + end + sort(axis,function(a,b) + return a.ordering=lastto then + else + values[#values+1]={ from,to } + lastfrom,lastto=from,to + end + end + nofvalues=#values + if nofvalues>2 then + local some=values[1] + if some[1]==-1 and some[2]==-1 then + some=values[nofvalues] + if some[1]==1 and some[2]==1 then + for i=2,nofvalues-1 do + some=values[i] + if some[1]==0 and some[2]==0 then + return values + end + end + end + end + end + return false + end + local version=readulong(f) + local reserved=readushort(f) + local nofaxis=readushort(f) + local segments={} + for i=1,nofaxis do + segments[i]=collect() + end + setvariabledata(fontdata,"segments",segments) + end +end +function readers.fvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"fvar",true) + if tableoffset then + local version=readulong(f) + local offsettoaxis=tableoffset+readushort(f) + local reserved=skipshort(f) + local nofaxis=readushort(f) + local sizeofaxis=readushort(f) + local nofinstances=readushort(f) + local sizeofinstances=readushort(f) + local extras=fontdata.extras + local axis={} + local instances={} + setposition(f,offsettoaxis) + for i=1,nofaxis do + axis[i]={ + tag=readtag(f), + minimum=readfixed(f), + default=readfixed(f), + maximum=readfixed(f), + flags=readushort(f), + name=lower(extras[readushort(f)] or "bad name"), + } + local n=sizeofaxis-20 + if n>0 then + skipbytes(f,n) + elseif n<0 then + end + end + local nofbytes=2+2+2+nofaxis*4 + local readpsname=nofbytes<=sizeofinstances + local skippable=sizeofinstances-nofbytes + for i=1,nofinstances do + local subfamid=readushort(f) + local flags=readushort(f) + local values={} + for i=1,nofaxis do + values[i]={ + axis=axis[i].tag, + value=readfixed(f), + } + end + local psnameid=readpsname and readushort(f) or 0xFFFF + if subfamid==2 or subfamid==17 then + elseif subfamid==0xFFFF then + subfamid=nil + elseif subfamid<=256 or subfamid>=32768 then + subfamid=nil + end + if psnameid==6 then + elseif psnameid==0xFFFF then + psnameid=nil + elseif psnameid<=256 or psnameid>=32768 then + psnameid=nil + end + instances[i]={ + subfamily=extras[subfamid], + psname=psnameid and extras[psnameid] or nil, + values=values, + } + if skippable>0 then + skipbytes(f,skippable) + end + end + setvariabledata(fontdata,"axis",axis) + setvariabledata(fontdata,"instances",instances) + end +end +function readers.hvar(f,fontdata,specification) + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) + if not tableoffset then + return + end + local version=readulong(f) + local variationoffset=tableoffset+readulong(f) + local advanceoffset=tableoffset+readulong(f) + local lsboffset=tableoffset+readulong(f) + local rsboffset=tableoffset+readulong(f) + local regions={} + local variations={} + local innerindex={} + local outerindex={} + if variationoffset>0 then + regions,deltas=readvariationdata(f,variationoffset,factors) + end + if not regions then + return + end + if advanceoffset>0 then + setposition(f,advanceoffset) + local format=readushort(f) + local mapcount=readushort(f) + local entrysize=rshift(band(format,0x0030),4)+1 + local nofinnerbits=band(format,0x000F)+1 + local innermask=lshift(1,nofinnerbits)-1 + local readcardinal=read_cardinal[entrysize] + for i=0,mapcount-1 do + local mapdata=readcardinal(f) + outerindex[i]=rshift(mapdata,nofinnerbits) + innerindex[i]=band(mapdata,innermask) + end + setvariabledata(fontdata,"hvarwidths",true) + local glyphs=fontdata.glyphs + for i=0,fontdata.nofglyphs-1 do + local glyph=glyphs[i] + local width=glyph.width + if width then + local outer=outerindex[i] or 0 + local inner=innerindex[i] or i + if outer and inner then + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local deltaw=0 + for i=1,#scales do + local di=d[i] + if di then + deltaw=deltaw+scales[i]*di + else + break + end + end + glyph.width=width+round(deltaw) + end + end + end + end + end + end +end +function readers.vvar(f,fontdata,specification) + if not specification.variable then + return + end +end +function readers.mvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) + if tableoffset then + local version=readulong(f) + local reserved=skipshort(f,1) + local recordsize=readushort(f) + local nofrecords=readushort(f) + local offsettostore=tableoffset+readushort(f) + local dimensions={} + local factors=specification.factors + if factors then + local regions,deltas=readvariationdata(f,offsettostore,factors) + for i=1,nofrecords do + local tag=readtag(f) + local var=variabletags[tag] + if var then + local outer=readushort(f) + local inner=readushort(f) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + dd=dd+scales[i]*d[i] + end + var(fontdata,round(dd)) + end + end + else + skipshort(f,2) + end + if recordsize>8 then + skipbytes(recordsize-8) + end + end + end + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup” 6f46aa00ae1c20c43f8ffaf329dc8695] --- + +if not modules then modules={} end modules ['font-oup']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local P,R,S=lpeg.P,lpeg.R,lpeg.S +local lpegmatch=lpeg.match +local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack +local formatters=string.formatters +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local tohash=table.tohash +local setmetatableindex=table.setmetatableindex +local report_error=logs.reporter("otf reader","error") +local report_markwidth=logs.reporter("otf reader","markwidth") +local report_cleanup=logs.reporter("otf reader","cleanup") +local report_optimizations=logs.reporter("otf reader","merges") +local report_unicodes=logs.reporter("otf reader","unicodes") +local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) +local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end) +local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end) +local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end) +local readers=fonts.handlers.otf.readers +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local f_private=formatters["P%05X"] +local f_unicode=formatters["U%05X"] +local f_index=formatters["I%05X"] +local f_character_y=formatters["%C"] +local f_character_n=formatters["[ %C ]"] +local check_duplicates=true +local check_soft_hyphen=true +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen=v +end) +local function replaced(list,index,replacement) + if type(list)=="number" then + return replacement + elseif type(replacement)=="table" then + local t={} + local n=index-1 + for i=1,n do + t[i]=list[i] + end + for i=1,#replacement do + n=n+1 + t[n]=replacement[i] + end + for i=index+1,#list do + n=n+1 + t[n]=list[i] + end + else + list[index]=replacement + return list + end +end +local function unifyresources(fontdata,indices) + local descriptions=fontdata.descriptions + local resources=fontdata.resources + if not descriptions or not resources then + return + end + local nofindices=#indices + local variants=fontdata.resources.variants + if variants then + for selector,unicodes in next,variants do + for unicode,index in next,unicodes do + unicodes[unicode]=indices[index] + end + end + end + local function remark(marks) + if marks then + local newmarks={} + for k,v in next,marks do + local u=indices[k] + if u then + newmarks[u]=v + elseif trace_optimizations then + report_optimizations("discarding mark %i",k) + end + end + return newmarks + end + end + local marks=resources.marks + if marks then + resources.marks=remark(marks) + end + local markclasses=resources.markclasses + if markclasses then + for class,marks in next,markclasses do + markclasses[class]=remark(marks) + end + end + local marksets=resources.marksets + if marksets then + for class,marks in next,marksets do + marksets[class]=remark(marks) + end + end + local done={} + local duplicates=check_duplicates and resources.duplicates + if duplicates and not next(duplicates) then + duplicates=false + end + local function recover(cover) + for i=1,#cover do + local c=cover[i] + if not done[c] then + local t={} + for k,v in next,c do + local ug=indices[k] + if ug then + t[ug]=v + else + report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) + end + end + cover[i]=t + done[c]=d + end + end + end + local function recursed(c,kind) + local t={} + for g,d in next,c do + if type(d)=="table" then + local ug=indices[g] + if ug then + t[ug]=recursed(d,kind) + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) + end + else + t[g]=indices[d] + end + end + return t + end + local function unifythem(sequences) + if not sequences then + return + end + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gsub_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local ud1=indices[d1] + if ud1 then + t1[ug1]=ud1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=ud1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=indices[d1] + else + report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_pair" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) + end + end + done[d1]=t2 + end + t1[ug1]=t2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gsub_ligature" then + local c=step.coverage + if c then + step.coverage=recursed(c,kind) + end + elseif kind=="gsub_alternate" or kind=="gsub_multiple" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) + end + end + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=copy(d1) + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) + end + end + t1[indices[g1]]=d1 + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=d1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + done[c]=t1 + end + step.coverage=t1 + end + local c=step.baseclasses + if c then + local t1=done[c] + if not t1 then + for g1,d1 in next,c do + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) + end + end + done[d1]=t2 + end + c[g1]=t2 + end + done[c]=c + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=copy(d1) + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + end + done[c]=t1 + end + step.coverage=t1 + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before if before then recover(before) end + local after=rule.after if after then recover(after) end + local current=rule.current if current then recover(current) end + local replacements=rule.replacements + if replacements then + if not done[replacements] then + local r={} + for k,v in next,replacements do + r[indices[k]]=indices[v] + end + rule.replacements=r + done[replacements]=r + end + end + end + end + end + end + end + end + unifythem(resources.sequences) + unifythem(resources.sublookups) +end +local function copyduplicates(fontdata) + if check_duplicates then + local descriptions=fontdata.descriptions + local resources=fontdata.resources + local duplicates=resources.duplicates + if check_soft_hyphen then + local ds=descriptions[0xAD] + if not ds or ds.width==0 then + if ds then + descriptions[0xAD]=nil + if trace_unicodes then + report_unicodes("patching soft hyphen") + end + else + if trace_unicodes then + report_unicodes("adding soft hyphen") + end + end + if not duplicates then + duplicates={} + resources.duplicates=duplicates + end + local dh=duplicates[0x2D] + if dh then + dh[#dh+1]={ [0xAD]=true } + else + duplicates[0x2D]={ [0xAD]=true } + end + end + end + if duplicates then + for u,d in next,duplicates do + local du=descriptions[u] + if du then + local t={ f_character_y(u),"@",f_index(du.index),"->" } + local n=0 + local m=25 + for u in next,d do + if descriptions[u] then + if n0 then + t={} + n=0 + local loops=0 + while true do + loops=loops+1 + local old=nofmissing + for i=1,#ligatures do + recursed(ligatures[i]) + end + if nofmissing<=0 then + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end + return + elseif old==nofmissing then + break + end + end + t=nil + n=0 + end + if trace_unicodes and nofmissing>0 then + local done={} + for i,r in next,missing do + if r then + local data=descriptions[i] + local name=data and data.name or f_index(i) + if not ignore[name] then + done[name]=true + end + end + end + if next(done) then + report_unicodes("not unicoded: % t",sortedkeys(done)) + end + end +end +local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst=0xE000 +local pualast=0xF8FF +local function unifymissing(fontdata) + if not fonts.mappings then + require("font-map") + require("font-agl") + end + local unicodes={} + local resources=fontdata.resources + resources.unicodes=unicodes + for unicode,d in next,fontdata.descriptions do + if unicode=puafirst and unicode<=pualast then + else + local name=d.name + if name then + unicodes[name]=unicode + end + end + else + end + end + fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) + resources.unicodes=nil +end +local function unifyglyphs(fontdata,usenames) + local private=fontdata.private or privateoffset + local glyphs=fontdata.glyphs + local indices={} + local descriptions={} + local names=usenames and {} + local resources=fontdata.resources + local zero=glyphs[0] + local zerocode=zero.unicode + if not zerocode then + zerocode=private + zero.unicode=zerocode + private=private+1 + end + descriptions[zerocode]=zero + if names then + local name=glyphs[0].name or f_private(zerocode) + indices[0]=name + names[name]=zerocode + else + indices[0]=zerocode + end + if names then + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + elseif unicode>=firstprivate then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + elseif descriptions[unicode] then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + else + local name=glyph.name or f_unicode(unicode) + indices[index]=name + names[name]=unicode + end + descriptions[unicode]=glyph + end + elseif trace_unicodes then + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + if name then + report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) + else + report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) + end + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + if name then + report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) + else + report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) + end + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + if name then + report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) + else + report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) + end + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph + end + else + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph + end + end + for index=1,#glyphs do + local math=glyphs[index].math + if math then + local list=math.vparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.hparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.vvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + local list=math.hvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + end + end + local colorpalettes=resources.colorpalettes + if colorpalettes then + for index=1,#glyphs do + local colors=glyphs[index].colors + if colors then + for i=1,#colors do + local c=colors[i] + c.slot=indices[c.slot] + end + end + end + end + fontdata.private=private + fontdata.glyphs=nil + fontdata.names=names + fontdata.descriptions=descriptions + fontdata.hashmethod=hashmethod + return indices,names +end +local p_crappyname do + local p_hex=R("af","AF","09") + local p_digit=R("09") + local p_done=S("._-")^0+P(-1) + local p_alpha=R("az","AZ") + local p_ALPHA=R("AZ") + p_crappyname=( + lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1 ++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1 ++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1 ++p_digit*p_hex^3+p_alpha*p_digit^1 ++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1 + )*p_done +end +local forcekeep=false +directives.register("otf.keepnames",function(v) + report_cleanup("keeping weird glyph names, expect larger files and more memory usage") + forcekeep=v +end) +local function stripredundant(fontdata) + local descriptions=fontdata.descriptions + if descriptions then + local n=0 + local c=0 + if (not context and fonts.privateoffsets.keepnames) or forcekeep then + for unicode,d in next,descriptions do + if d.class=="base" then + d.class=nil + c=c+1 + end + end + else + for unicode,d in next,descriptions do + local name=d.name + if name and lpegmatch(p_crappyname,name) then + d.name=nil + n=n+1 + end + if d.class=="base" then + d.class=nil + c=c+1 + end + end + end + if trace_cleanup then + if n>0 then + report_cleanup("%s bogus names removed (verbose unicode)",n) + end + if c>0 then + report_cleanup("%s base class tags removed (default is base)",c) + end + end + end +end +readers.stripredundant=stripredundant +function readers.getcomponents(fontdata) + local resources=fontdata.resources + if resources then + local sequences=resources.sequences + if sequences then + local collected={} + for i=1,#sequences do + local sequence=sequences[i] + if sequence.type=="gsub_ligature" then + local steps=sequence.steps + if steps then + local l={} + local function traverse(p,k,v) + if k=="ligature" then + collected[v]={ unpack(l) } + else + insert(l,k) + for k,vv in next,v do + traverse(p,k,vv) + end + remove(l) + end + end + for i=1,#steps do + local c=steps[i].coverage + if c then + for k,v in next,c do + traverse(k,k,v) + end + end + end + end + end + end + if next(collected) then + while true do + local done=false + for k,v in next,collected do + for i=1,#v do + local vi=v[i] + if vi==k then + collected[k]=nil + break + else + local c=collected[vi] + if c then + done=true + local t={} + local n=i-1 + for j=1,n do + t[j]=v[j] + end + for j=1,#c do + n=n+1 + t[n]=c[j] + end + for j=i+1,#v do + n=n+1 + t[n]=v[j] + end + collected[k]=t + break + end + end + end + end + if not done then + break + end + end + return collected + end + end + end +end +readers.unifymissing=unifymissing +function readers.rehash(fontdata,hashmethod) + if not (fontdata and fontdata.glyphs) then + return + end + if hashmethod=="indices" then + fontdata.hashmethod="indices" + elseif hashmethod=="names" then + fontdata.hashmethod="names" + local indices=unifyglyphs(fontdata,true) + unifyresources(fontdata,indices) + copyduplicates(fontdata) + unifymissing(fontdata) + else + fontdata.hashmethod="unicodes" + local indices=unifyglyphs(fontdata) + unifyresources(fontdata,indices) + copyduplicates(fontdata) + unifymissing(fontdata) + stripredundant(fontdata) + end +end +function readers.checkhash(fontdata) + local hashmethod=fontdata.hashmethod + if hashmethod=="unicodes" then + fontdata.names=nil + elseif hashmethod=="names" and fontdata.names then + unifyresources(fontdata,fontdata.names) + copyduplicates(fontdata) + fontdata.hashmethod="unicodes" + fontdata.names=nil + else + readers.rehash(fontdata,"unicodes") + end +end +function readers.addunicodetable(fontdata) + local resources=fontdata.resources + local unicodes=resources.unicodes + if not unicodes then + local descriptions=fontdata.descriptions + if descriptions then + unicodes={} + resources.unicodes=unicodes + for u,d in next,descriptions do + local n=d.name + if n then + unicodes[n]=u + end + end + end + end +end +local concat,sort=table.concat,table.sort +local next,type,tostring=next,type,tostring +local criterium=1 +local threshold=0 +local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local function tabstr_normal(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + if type(v)=="table" then + s[n]=k..">"..tabstr_normal(v) + elseif v==true then + s[n]=k.."+" + elseif v then + s[n]=k.."="..v + else + s[n]=k.."-" + end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_flat(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + s[n]=k.."="..v + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_mixed(t) + local s={} + local n=#t + if n==0 then + return "" + elseif n==1 then + local k=t[1] + if k==true then + return "++" + elseif k==false then + return "--" + else + return tostring(k) + end + else + for i=1,n do + local k=t[i] + if k==true then + s[i]="++" + elseif k==false then + s[i]="--" + else + s[i]=k + end + end + return concat(s,",") + end +end +local function tabstr_boolean(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + if v then + s[n]=k.."+" + else + s[n]=k.."-" + end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +function readers.pack(data) + if data then + local h,t,c={},{},{} + local hh,tt,cc={},{},{} + local nt,ntt=0,0 + local function pack_normal(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_normal_cc(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + v[1]=0 + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_flat(v) + local tag=tabstr_flat(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_indexed(v) + local tag=concat(v," ") + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_mixed(v) + local tag=tabstr_mixed(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_boolean(v) + local tag=tabstr_boolean(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_final(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt + end + end + end + local function pack_final_cc(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt + end + end + end + local function success(stage,pass) + if nt==0 then + if trace_loading or trace_packing then + report_otf("pack quality: nothing to pack") + end + return false + elseif nt>=threshold then + local one=0 + local two=0 + local rest=0 + if pass==1 then + for k,v in next,c do + if v==1 then + one=one+1 + elseif v==2 then + two=two+1 + else + rest=rest+1 + end + end + else + for k,v in next,cc do + if v>20 then + rest=rest+1 + elseif v>10 then + two=two+1 + else + one=one+1 + end + end + data.tables=tt + end + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", + stage,pass,one+two+rest,one,two,rest,criterium) + end + return true + else + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", + stage,pass,nt,threshold) + end + return false + end + end + local function packers(pass) + if pass==1 then + return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc + else + return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc + end + end + local resources=data.resources + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local chardata=characters and characters.data + local descriptions=data.descriptions or data.glyphs + if not descriptions then + return + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 1, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local boundingbox=description.boundingbox + if boundingbox then + description.boundingbox=pack_indexed(boundingbox) + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + for tag,kern in next,kerns do + kerns[tag]=pack_normal(kern) + end + end + end + end + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format~="pair" then + for g1,d1 in next,c do + c[g1]=pack_normal(d1) + end + elseif step.shared then + local shared={} + for g1,d1 in next,c do + for g2,d2 in next,d1 do + if not shared[d2] then + local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end + local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end + shared[d2]=true + end + end + end + if pass==2 then + step.shared=nil + end + else + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end + local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end + end + end + end + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + if d1 and d1~=true then + c[g1]=pack_indexed(d1) + end + end + else + step.coverage=pack_normal(c) + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local f=d1[2] if f then d1[2]=pack_indexed(f) end + local s=d1[3] if s then d1[3]=pack_indexed(s) end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_indexed(d2) + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + for g3,d3 in next,d2 do + d2[g3]=pack_indexed(d3) + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.replacements if r then rule.replacements=pack_flat (r) end + end + end + end + end + if order then + sequence.order=pack_indexed(order) + end + if features then + for script,feature in next,features do + features[script]=pack_normal(feature) + end + end + if flags then + sequence.flags=pack_normal(flags) + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + list[feature]=pack_normal(spec) + end + end + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + p[j]=pack_indexed(p[j]) + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + v[j]=pack_normal(v[j]) + end + end + end + local function packdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + for j=1,#d do + d[j]=pack_indexed(d[j]) + end + di.regions=pack_indexed(di.regions) + end + end + local regions=main.regions + if regions then + for i=1,#regions do + local r=regions[i] + for j=1,#r do + r[j]=pack_normal(r[j]) + end + end + end + end + end + packdeltas(variable.global) + packdeltas(variable.horizontal) + packdeltas(variable.vertical) + packdeltas(variable.metrics) + end + if not success(1,pass) then + return + end + end + if nt>0 then + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 2, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local math=description.math + if math then + local kerns=math.kerns + if kerns then + math.kerns=pack_normal(kerns) + end + end + end + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then rule.before=pack_normal(r) end + local r=rule.after if r then rule.after=pack_normal(r) end + local r=rule.current if r then rule.current=pack_normal(r) end + end + end + end + end + if features then + sequence.features=pack_normal(features) + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + if variable then + local function unpackdeltas(main) + if main then + local regions=main.regions + if regions then + main.regions=pack_normal(regions) + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 3, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + c[g1]=pack_normal(d1) + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + c[g1]=pack_normal_cc(d1) + end + end + end + end + end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + end + end + end +end +local unpacked_mt={ + __index=function(t,k) + t[k]=false + return k + end +} +function readers.unpack(data) + if data then + local tables=data.tables + if tables then + local resources=data.resources + local descriptions=data.descriptions or data.glyphs + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local unpacked={} + setmetatable(unpacked,unpacked_mt) + for unicode,description in next,descriptions do + local tv=tables[description.boundingbox] + if tv then + description.boundingbox=tv + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + local tm=tables[kerns] + if tm then + math.kerns=tm + kerns=unpacked[tm] + end + if kerns then + for k,kern in next,kerns do + local tv=tables[kern] + if tv then + kerns[k]=tv + end + end + end + end + end + end + local function unpackthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + local markclass=sequence.markclass + if features then + local tv=tables[features] + if tv then + sequence.features=tv + features=tv + end + for script,feature in next,features do + local tv=tables[feature] + if tv then + features[script]=tv + end + end + end + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + d1=tv + end + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + d2=tv + end + local f=tables[d2[1]] if f then d2[1]=f end + local s=tables[d2[2]] if s then d2[2]=s end + end + end + else + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end + end + end + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end + end + else + local tv=tables[c] + if tv then + step.coverage=tv + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + d1=tv + c[g1]=d1 + end + local f=tables[d1[2]] if f then d1[2]=f end + local s=tables[d1[3]] if s then d1[3]=s end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv + end + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d2=tv + d1[g2]=d2 + end + for g3,d3 in next,d2 do + local tv=tables[d2[g3]] + if tv then + d2[g3]=tv + end + end + end + end + end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv + end + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + if before then + local tv=tables[before] + if tv then + rule.before=tv + before=tv + end + for i=1,#before do + local tv=tables[before[i]] + if tv then + before[i]=tv + end + end + end + local after=rule.after + if after then + local tv=tables[after] + if tv then + rule.after=tv + after=tv + end + for i=1,#after do + local tv=tables[after[i]] + if tv then + after[i]=tv + end + end + end + local current=rule.current + if current then + local tv=tables[current] + if tv then + rule.current=tv + current=tv + end + for i=1,#current do + local tv=tables[current[i]] + if tv then + current[i]=tv + end + end + end + local replacements=rule.replacements + if replacements then + local tv=tables[replacements] + if tv then + rule.replacements=tv + end + end + end + end + end + end + if order then + local tv=tables[order] + if tv then + sequence.order=tv + end + end + if flags then + local tv=tables[flags] + if tv then + sequence.flags=tv + end + end + end + end + if sequences then + unpackthem(sequences) + end + if sublookups then + unpackthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + local tv=tables[spec] + if tv then + list[feature]=tv + end + end + end + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + local tv=tables[p[j]] + if tv then + p[j]=tv + end + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + local tv=tables[v[j]] + if tv then + v[j]=tv + end + end + end + end + local function unpackdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + local r=di.regions + for j=1,#d do + local tv=tables[d[j]] + if tv then + d[j]=tv + end + end + local tv=di.regions + if tv then + di.regions=tv + end + end + end + local regions=main.regions + if regions then + local tv=tables[regions] + if tv then + main.regions=tv + regions=tv + end + for i=1,#regions do + local r=regions[i] + for j=1,#r do + local tv=tables[r[j]] + if tv then + r[j]=tv + end + end + end + end + end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + data.tables=nil + end + end +end +local mt={ + __index=function(t,k) + if k=="height" then + local ht=t.boundingbox[4] + return ht<0 and 0 or ht + elseif k=="depth" then + local dp=-t.boundingbox[2] + return dp<0 and 0 or dp + elseif k=="width" then + return 0 + elseif k=="name" then + return forcenotdef and ".notdef" + end + end +} +local function sameformat(sequence,steps,first,nofsteps,kind) + return true +end +local function mergesteps_1(lookup,strict) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format + for i=2,nofsteps do + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + if not target[k] then + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_2(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format + for i=2,nofsteps do + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + for kk,vv in next,v do + if tk[kk]==nil then + tk[kk]=vv + end + end + else + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_3(lookup,strict) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local coverage={} + for i=1,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=coverage[k] + if tk then + if trace_optimizations then + report_optimizations("quitting merge due to multiple checks") + end + return nofsteps + else + coverage[k]=v + end + end + end + end + local first=steps[1] + local baseclasses={} + for i=1,nofsteps do + local offset=i*10 + local step=steps[i] + for k,v in sortedhash(step.baseclasses) do + baseclasses[offset+k]=v + end + for k,v in next,step.coverage do + v[1]=offset+v[1] + end + end + first.baseclasses=baseclasses + first.coverage=coverage + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function nested(old,new) + for k,v in next,old do + if k=="ligature" then + if not new.ligature then + new.ligature=v + end + else + local n=new[k] + if n then + nested(v,n) + else + new[k]=v + end + end + end +end +local function mergesteps_4(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + nested(v,tk) + else + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.steps={ first } + return nofsteps-1 +end +local function mergesteps_5(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + local hash=nil + for k,v in next,target do + hash=v[1] + break + end + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + if not tk[2] then + tk[2]=v[2] + end + if not tk[3] then + tk[3]=v[3] + end + else + target[k]=v + v[1]=hash + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 +end +local function checkkerns(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=step.coverage + local kerns=true + for g1,d1 in next,coverage do + if d1==true then + elseif not d1 then + elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then + kerns=false + break + end + end + if kerns then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + local c={} + for g1,d1 in next,coverage do + if d1 and d1~=true then + c[g1]=d1[3] + end + end + step.coverage=c + step.format="move" + kerned=kerned+1 + end + end + end + return kerned +end +local function checkpairs(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + local function onlykerns(step) + local coverage=step.coverage + for g1,d1 in next,coverage do + for g2,d2 in next,d1 do + if d2[2] then + return false + else + local v=d2[1] + if v==true then + elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then + return false + end + end + end + end + return coverage + end + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=onlykerns(step) + if coverage then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + for g1,d1 in next,coverage do + local d={} + for g2,d2 in next,d1 do + local v=d2[1] + if v==true then + elseif v then + d[g2]=v[3] + end + end + coverage[g1]=d + end + step.format="move" + kerned=kerned+1 + end + end + end + return kerned +end +local compact_pairs=true +local compact_singles=true +local merge_pairs=true +local merge_singles=true +local merge_substitutions=true +local merge_alternates=true +local merge_multiples=true +local merge_ligatures=true +local merge_cursives=true +local merge_marks=true +directives.register("otf.compact.pairs",function(v) compact_pairs=v end) +directives.register("otf.compact.singles",function(v) compact_singles=v end) +directives.register("otf.merge.pairs",function(v) merge_pairs=v end) +directives.register("otf.merge.singles",function(v) merge_singles=v end) +directives.register("otf.merge.substitutions",function(v) merge_substitutions=v end) +directives.register("otf.merge.alternates",function(v) merge_alternates=v end) +directives.register("otf.merge.multiples",function(v) merge_multiples=v end) +directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end) +directives.register("otf.merge.cursives",function(v) merge_cursives=v end) +directives.register("otf.merge.marks",function(v) merge_marks=v end) +function readers.compact(data) + if not data or data.compacted then + return + else + data.compacted=true + end + local resources=data.resources + local merged=0 + local kerned=0 + local allsteps=0 + local function compact(what) + local lookups=resources[what] + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local nofsteps=lookup.nofsteps + local kind=lookup.type + allsteps=allsteps+nofsteps + if nofsteps>1 then + local merg=merged + if kind=="gsub_single" then + if merge_substitutions then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_alternate" then + if merge_alternates then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_multiple" then + if merge_multiples then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_ligature" then + if merge_ligatures then + merged=merged+mergesteps_4(lookup) + end + elseif kind=="gpos_single" then + if merge_singles then + merged=merged+mergesteps_1(lookup,true) + end + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if merge_pairs then + merged=merged+mergesteps_2(lookup) + end + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + elseif kind=="gpos_cursive" then + if merge_cursives then + merged=merged+mergesteps_5(lookup) + end + elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then + if merge_marks then + merged=merged+mergesteps_3(lookup) + end + end + if merg~=merged then + lookup.merged=true + end + elseif nofsteps==1 then + local kern=kerned + if kind=="gpos_single" then + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + end + if kern~=kerned then + end + end + end + elseif trace_optimizations then + report_optimizations("no lookups in %a",what) + end + end + compact("sequences") + compact("sublookups") + if trace_optimizations then + if merged>0 then + report_optimizations("%i steps of %i removed due to merging",merged,allsteps) + end + if kerned>0 then + report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) + end + end +end +local function mergesteps(t,k) + if k=="merged" then + local merged={} + for i=1,#t do + local step=t[i] + local coverage=step.coverage + for k in next,coverage do + local m=merged[k] + if m then + m[2]=i + else + merged[k]={ i,i } + end + end + end + t.merged=merged + return merged + end +end +local function checkmerge(sequence) + local steps=sequence.steps + if steps then + setmetatableindex(steps,mergesteps) + end +end +local function checkflags(sequence,resources) + if not sequence.skiphash then + local flags=sequence.flags + if flags then + local skipmark=flags[1] + local skipligature=flags[2] + local skipbase=flags[3] + local markclass=sequence.markclass + local skipsome=skipmark or skipligature or skipbase or markclass or false + if skipsome then + sequence.skiphash=setmetatableindex(function(t,k) + local c=resources.classes[k] + local v=c==skipmark + or (markclass and c=="mark" and not markclass[k]) + or c==skipligature + or c==skipbase + or false + t[k]=v + return v + end) + else + sequence.skiphash=false + end + else + sequence.skiphash=false + end + end +end +local function checksteps(sequence) + local steps=sequence.steps + if steps then + for i=1,#steps do + steps[i].index=i + end + end +end +if fonts.helpers then + fonts.helpers.checkmerge=checkmerge + fonts.helpers.checkflags=checkflags + fonts.helpers.checksteps=checksteps +end +function readers.expand(data) + if not data or data.expanded then + return + else + data.expanded=true + end + local resources=data.resources + local sublookups=resources.sublookups + local sequences=resources.sequences + local markclasses=resources.markclasses + local descriptions=data.descriptions + if descriptions then + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local basename=trace_markwidth and file.basename(resources.filename) + for u,d in next,descriptions do + local bb=d.boundingbox + local wd=d.width + if not wd then + d.width=defaultwidth + elseif trace_markwidth and wd~=0 and d.class=="mark" then + report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) + end + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then + else + d.height=ht + end + if dp==0 or dp<0 then + else + d.depth=dp + end + end + end + end + local function expandlookups(sequences) + if sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local nofsteps=sequence.nofsteps + local kind=sequence.type + local markclass=sequence.markclass + if markclass then + if not markclasses then + report_warning("missing markclasses") + sequence.markclass=false + else + sequence.markclass=markclasses[markclass] + end + end + for i=1,nofsteps do + local step=steps[i] + local baseclasses=step.baseclasses + if baseclasses then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=baseclasses[v[1]] + end + elseif kind=="gpos_cursive" then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=coverage + end + end + local rules=step.rules + if rules then + local rulehash={ n=0 } + local rulesize=0 + local coverage={} + local lookuptype=sequence.type + local nofrules=#rules + step.coverage=coverage + for currentrule=1,nofrules do + local rule=rules[currentrule] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups then + for i=1,#lookups do + local lookups=lookups[i] + if lookups then + for k,v in next,lookups do + local lookup=sublookups[v] + if lookup then + lookups[k]=lookup + if not subtype then + subtype=lookup.type + end + else + end + end + end + end + end + if sequence[1] then + sequence.n=#sequence + local ruledata={ + currentrule, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + rulesize=rulesize+1 + rulehash[rulesize]=ruledata + rulehash.n=rulesize + if true then + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + local n=#cu+1 + cu[n]=ruledata + cu.n=n + else + coverage[unic]={ ruledata,n=1 } + end + end + else + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + else + coverage[unic]=rulehash + end + end + end + end + end + end + end + checkmerge(sequence) + checkflags(sequence,resources) + checksteps(sequence) + end + end + end + end + expandlookups(sequences) + expandlookups(sublookups) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl” 6c4b718ceacfb0cbeb2c03c423f97aec] --- + +if not modules then modules={} end modules ['font-otl']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local lower=string.lower +local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack +local abs=math.abs +local derivetable=table.derive +local formatters=string.formatters +local setmetatableindex=table.setmetatableindex +local allocate=utilities.storage.allocate +local registertracker=trackers.register +local registerdirective=directives.register +local starttiming=statistics.starttiming +local stoptiming=statistics.stoptiming +local elapsedtime=statistics.elapsedtime +local findbinfile=resolvers.findbinfile +local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) +local trace_features=false registertracker("otf.features",function(v) trace_features=v end) +local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +otf.version=3.112 +otf.cache=containers.define("fonts","otl",otf.version,true) +otf.svgcache=containers.define("fonts","svg",otf.version,true) +otf.pngcache=containers.define("fonts","png",otf.version,true) +otf.pdfcache=containers.define("fonts","pdf",otf.version,true) +otf.mpscache=containers.define("fonts","mps",otf.version,true) +otf.svgenabled=false +otf.pngenabled=false +local otfreaders=otf.readers +local hashes=fonts.hashes +local definers=fonts.definers +local readers=fonts.readers +local constructors=fonts.constructors +local otffeatures=constructors.features.otf +local registerotffeature=otffeatures.register +local otfenhancers=constructors.enhancers.otf +local registerotfenhancer=otfenhancers.register +local forceload=false +local cleanup=0 +local syncspace=true +local forcenotdef=false +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes +local wildcard="*" +local default="dflt" +local formats=fonts.formats +formats.otf="opentype" +formats.ttf="truetype" +formats.ttc="truetype" +registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end) +registerdirective("fonts.otf.loader.force",function(v) forceload=v end) +registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end) +registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end) +registerotfenhancer("check extra features",function() end) +local checkmemory=utilities.lua and utilities.lua.checkmemory +local threshold=100 +local tracememory=false +registertracker("fonts.otf.loader.memory",function(v) tracememory=v end) +if not checkmemory then + local collectgarbage=collectgarbage + checkmemory=function(previous,threshold) + local current=collectgarbage("count") + if previous then + local checked=(threshold or 64)*1024 + if current-previous>checked then + collectgarbage("collect") + current=collectgarbage("count") + end + end + return current + end +end +function otf.load(filename,sub,instance) + local base=file.basename(file.removesuffix(filename)) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if sub=="" then + sub=false + end + local hash=name + if sub then + hash=hash.."-"..sub + end + if instance then + hash=hash.."-"..instance + end + hash=containers.cleanname(hash) + local data=containers.read(otf.cache,hash) + local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion + if forceload then + report_otf("forced reload of %a due to hard coded flag",filename) + reload=true + end + if reload then + report_otf("loading %a, hash %a",filename,hash) + starttiming(otfreaders,true) + data=otfreaders.loadfont(filename,sub or 1,instance) + if data then + local used=checkmemory() + local resources=data.resources + local svgshapes=resources.svgshapes + local pngshapes=resources.pngshapes + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + if svgshapes then + resources.svgshapes=nil + if otf.svgenabled then + local timestamp=os.date() + containers.write(otf.svgcache,hash,{ + svgshapes=svgshapes, + timestamp=timestamp, + }) + data.properties.svg={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + if pngshapes then + resources.pngshapes=nil + if otf.pngenabled then + local timestamp=os.date() + containers.write(otf.pngcache,hash,{ + pngshapes=pngshapes, + timestamp=timestamp, + }) + data.properties.png={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + otfreaders.compact(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.rehash(data,"unicodes") + otfreaders.addunicodetable(data) + otfreaders.extend(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.pack(data) + report_otf("loading done") + report_otf("saving %a in cache",filename) + data=containers.write(otf.cache,hash,data) + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + stoptiming(otfreaders) + if elapsedtime then + report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) + end + if cleanup>3 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + data=containers.read(otf.cache,hash) + if cleanup>2 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + else + stoptiming(otfreaders) + data=nil + report_otf("loading failed due to read error") + end + end + if data then + if trace_defining then + report_otf("loading from cache using hash %a",hash) + end + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + data.metadata.math=data.resources.mathconstants + local classes=data.resources.classes + if not classes then + local descriptions=data.descriptions + classes=setmetatableindex(function(t,k) + local d=descriptions[k] + local v=(d and d.class or "base") or false + t[k]=v + return v + end) + data.resources.classes=classes + end + end + return data +end +function otf.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) + if okay then + return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) + else + return {} + end +end +local function copytotfm(data,cache_id) + if data then + local metadata=data.metadata + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local mathparameters={} + local resources=data.resources + local unicodes=resources.unicodes + local spaceunits=500 + local spacer="space" + local designsize=metadata.designsize or 100 + local minsize=metadata.minsize or designsize + local maxsize=metadata.maxsize or designsize + local mathspecs=metadata.math + if designsize==0 then + designsize=100 + minsize=100 + maxsize=100 + end + if mathspecs then + for name,value in next,mathspecs do + mathparameters[name]=value + end + end + for unicode in next,data.descriptions do + characters[unicode]={} + end + if mathspecs then + for unicode,character in next,characters do + local d=descriptions[unicode] + local m=d.math + if m then + local italic=m.italic + local vitalic=m.vitalic + local variants=m.hvariants + local parts=m.hparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.horiz_variants=parts + elseif parts then + character.horiz_variants=parts + italic=m.hitalic + end + local variants=m.vvariants + local parts=m.vparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.vert_variants=parts + elseif parts then + character.vert_variants=parts + end + if italic and italic~=0 then + character.italic=italic + end + if vitalic and vitalic~=0 then + character.vert_italic=vitalic + end + local accent=m.accent + if accent then + character.accent=accent + end + local kerns=m.kerns + if kerns then + character.mathkerns=kerns + end + end + end + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname + local fullname=metadata.fullname or fontname + local psname=fontname or fullname + local subfont=metadata.subfontindex + local units=metadata.units or 1000 + if units==0 then + units=1000 + metadata.units=1000 + report_otf("changing %a units to %a",0,units) + end + local monospaced=metadata.monospaced + local charwidth=metadata.averagewidth + local charxheight=metadata.xheight + local italicangle=metadata.italicangle + local hasitalics=metadata.hasitalics + properties.monospaced=monospaced + properties.hasitalics=hasitalics + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + local space=0x0020 + local emdash=0x2014 + if monospaced then + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width,"emdash" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + else + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + end + spaceunits=tonumber(spaceunits) or units/2 + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=1*units/2 + parameters.space_shrink=1*units/3 + parameters.x_height=2*units/5 + parameters.quad=units + if spaceunits<2*units/5 then + end + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + parameters.designsize=(designsize/10)*65536 + parameters.minsize=(minsize/10)*65536 + parameters.maxsize=(maxsize/10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=units + parameters.vheight=metadata.defaultvheight + properties.space=spacer + properties.format=data.format or formats.otf + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=psname + properties.name=filename or fullname + properties.subfont=subfont +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end + properties.private=properties.private or data.private or privateoffset + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + mathparameters=mathparameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end +end +local converters={ + woff={ + cachename="webfonts", + action=otf.readers.woff2otf, + } +} +local function checkconversion(specification) + local filename=specification.filename + local converter=converters[lower(file.suffix(filename))] + if converter then + local base=file.basename(filename) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if size>0 then + local cleanname=containers.cleanname(name) + local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) + lfs.touch(cachename,time,time) + end + specification.filename=cachename + end + end +end +local function otftotfm(specification) + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + checkconversion(specification) + local name=specification.name + local sub=specification.sub + local subindex=specification.subindex + local filename=specification.filename + local features=specification.features.normal + local instance=specification.instance or (features and features.axis) + local rawdata=otf.load(filename,sub,instance) + if rawdata and next(rawdata) then + local descriptions=rawdata.descriptions + rawdata.lookuphash={} + tfmdata=copytotfm(rawdata,cache_id) + if tfmdata and next(tfmdata) then + local features=constructors.checkedfeatures("otf",features) + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared + end + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=otf.setfeatures(tfmdata,features) + end + end + containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata +end +local function read_from_otf(specification) + local tfmdata=otftotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata.properties.sub=specification.sub + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) + constructors.setname(tfmdata,specification) + fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) + end + return tfmdata +end +local function checkmathsize(tfmdata,mathsize) + local mathdata=tfmdata.shared.rawdata.metadata.math + local mathsize=tonumber(mathsize) + if mathdata then + local parameters=tfmdata.parameters + parameters.scriptpercentage=mathdata.ScriptPercentScaleDown + parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown + parameters.mathsize=mathsize + end +end +registerotffeature { + name="mathsize", + description="apply mathsize specified in the font", + initializers={ + base=checkmathsize, + node=checkmathsize, + } +} +function otf.collectlookups(rawdata,kind,script,language) + if not kind then + return + end + if not script then + script=default + end + if not language then + language=default + end + local lookupcache=rawdata.lookupcache + if not lookupcache then + lookupcache={} + rawdata.lookupcache=lookupcache + end + local kindlookup=lookupcache[kind] + if not kindlookup then + kindlookup={} + lookupcache[kind]=kindlookup + end + local scriptlookup=kindlookup[script] + if not scriptlookup then + scriptlookup={} + kindlookup[script]=scriptlookup + end + local languagelookup=scriptlookup[language] + if not languagelookup then + local sequences=rawdata.resources.sequences + local featuremap={} + local featurelist={} + if sequences then + for s=1,#sequences do + local sequence=sequences[s] + local features=sequence.features + if features then + features=features[kind] + if features then + features=features[script] or features[wildcard] + if features then + features=features[language] or features[wildcard] + if features then + if not featuremap[sequence] then + featuremap[sequence]=true + featurelist[#featurelist+1]=sequence + end + end + end + end + end + end + if #featurelist==0 then + featuremap,featurelist=false,false + end + else + featuremap,featurelist=false,false + end + languagelookup={ featuremap,featurelist } + scriptlookup[language]=languagelookup + end + return unpack(languagelookup) +end +local function getgsub(tfmdata,k,kind,value) + local shared=tfmdata.shared + local rawdata=shared and shared.rawdata + if rawdata then + local sequences=rawdata.resources.sequences + if sequences then + local properties=tfmdata.properties + local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) + if validlookups then + for i=1,#lookuplist do + local lookup=lookuplist[i] + local steps=lookup.steps + local nofsteps=lookup.nofsteps + for i=1,nofsteps do + local coverage=steps[i].coverage + if coverage then + local found=coverage[k] + if found then + return found,lookup.type + end + end + end + end + end + end + end +end +otf.getgsub=getgsub +function otf.getsubstitution(tfmdata,k,kind,value) + local found,kind=getgsub(tfmdata,k,kind,value) + if not found then + elseif kind=="gsub_single" then + return found + elseif kind=="gsub_alternate" then + local choice=tonumber(value) or 1 + return found[choice] or found[1] or k + end + return k +end +otf.getalternate=otf.getsubstitution +function otf.getmultiple(tfmdata,k,kind) + local found,kind=getgsub(tfmdata,k,kind) + if found and kind=="gsub_multiple" then + return found + end + return { k } +end +function otf.getkern(tfmdata,left,right,kind) + local kerns=getgsub(tfmdata,left,kind or "kern",true) + if kerns then + local found=kerns[right] + local kind=type(found) + if kind=="table" then + found=found[1][3] + elseif kind~="number" then + found=false + end + if found then + return found*tfmdata.parameters.factor + end + end + return 0 +end +local function check_otf(forced,specification,suffix) + local name=specification.name + if forced then + name=specification.forcedname + end + local fullname=findbinfile(name,suffix) or "" + if fullname=="" then + fullname=fonts.names.getfilename(name,suffix) or "" + end + if fullname~="" and not fonts.names.ignoredfile(fullname) then + specification.filename=fullname + return read_from_otf(specification) + end +end +local function opentypereader(specification,suffix) + local forced=specification.forced or "" + if formats[forced] then + return check_otf(true,specification,forced) + else + return check_otf(false,specification,suffix) + end +end +readers.opentype=opentypereader +function readers.otf(specification) return opentypereader(specification,"otf") end +function readers.ttf(specification) return opentypereader(specification,"ttf") end +function readers.ttc(specification) return opentypereader(specification,"ttf") end +function readers.woff(specification) + checkconversion(specification) + opentypereader(specification,"") +end +function otf.scriptandlanguage(tfmdata,attr) + local properties=tfmdata.properties + return properties.script or "dflt",properties.language or "dflt" +end +local function justset(coverage,unicode,replacement) + coverage[unicode]=replacement +end +otf.coverup={ + stepkey="steps", + actions={ + chainsubstitution=justset, + chainposition=justset, + substitution=justset, + alternate=justset, + multiple=justset, + kern=justset, + pair=justset, + single=justset, + ligature=function(coverage,unicode,ligature) + local first=ligature[1] + local tree=coverage[first] + if not tree then + tree={} + coverage[first]=tree + end + for i=2,#ligature do + local l=ligature[i] + local t=tree[l] + if not t then + t={} + tree[l]=t + end + tree=t + end + tree.ligature=unicode + end, + }, + register=function(coverage,featuretype,format) + return { + format=format, + coverage=coverage, + } + end +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto” 2b1d6bc63b2ebf8f2655a15e1cda6541] --- + +if not modules then modules={} end modules ['font-oto']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local concat,unpack=table.concat,table.unpack +local insert,remove=table.insert,table.remove +local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip +local type,next,tonumber,tostring=type,next,tonumber,tostring +local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) +local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) +local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) +local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) +local report_prepare=logs.reporter("fonts","otf prepare") +local fonts=fonts +local otf=fonts.handlers.otf +local otffeatures=otf.features +local registerotffeature=otffeatures.register +otf.defaultbasealternate="none" +local getprivate=fonts.constructors.getprivate +local wildcard="*" +local default="dflt" +local formatters=string.formatters +local f_unicode=formatters["%U"] +local f_uniname=formatters["%U (%s)"] +local f_unilist=formatters["% t (% t)"] +local function gref(descriptions,n) + if type(n)=="number" then + local name=descriptions[n].name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local num={} + local nam={} + local j=0 + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + j=j+1 + local di=descriptions[ni] + num[j]=f_unicode(ni) + nam[j]=di and di.name or "-" + end + end + return f_unilist(num,nam) + else + return "" + end +end +local function cref(feature,sequence) + return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) +end +local function report_substitution(feature,sequence,descriptions,unicode,substitution) + if unicode==substitution then + report_prepare("%s: base substitution %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base substitution %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,substitution)) + end +end +local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment) + if unicode==replacement then + report_prepare("%s: base alternate %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base alternate %s => %s (%S => %S)", + cref(feature,sequence), + gref(descriptions,unicode), + replacement and gref(descriptions,replacement), + value, + comment) + end +end +local function report_ligature(feature,sequence,descriptions,unicode,ligature) + report_prepare("%s: base ligature %s => %S", + cref(feature,sequence), + gref(descriptions,ligature), + gref(descriptions,unicode)) +end +local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value) + report_prepare("%s: base kern %s + %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,otherunicode), + value) +end +local basehash,basehashes,applied={},1,{} +local function registerbasehash(tfmdata) + local properties=tfmdata.properties + local hash=concat(applied," ") + local base=basehash[hash] + if not base then + basehashes=basehashes+1 + base=basehashes + basehash[hash]=base + end + properties.basehash=base + properties.fullname=(properties.fullname or properties.name).."-"..base + applied={} +end +local function registerbasefeature(feature,value) + applied[#applied+1]=feature.."="..tostring(value) +end +local function makefake(tfmdata,name,present) + local private=getprivate(tfmdata) + local character={ intermediate=true,ligatures={} } + resources.unicodes[name]=private + tfmdata.characters[private]=character + tfmdata.descriptions[private]={ name=name } + present[name]=private + return character +end +local function make_1(present,tree,name) + for k,v in next,tree do + if k=="ligature" then + present[name]=v + else + make_1(present,v,name.."_"..k) + end + end +end +local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done) + for k,v in next,tree do + if k=="ligature" then + local character=characters[preceding] + if not character then + if trace_baseinit then + report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) + end + character=makefake(tfmdata,name,present) + end + local ligatures=character.ligatures + if ligatures then + ligatures[unicode]={ char=v } + else + character.ligatures={ [unicode]={ char=v } } + end + if done then + local d=done[name] + if not d then + done[name]={ "dummy",v } + else + d[#d+1]=v + end + end + else + local code=present[name] or unicode + local name=name.."_"..k + make_2(present,tfmdata,characters,v,name,code,k,done) + end + end +end +local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local changed=tfmdata.changed + local ligatures={} + local alternate=tonumber(value) or true and 1 + local defaultalt=otf.defaultbasealternate + local trace_singles=trace_baseinit and trace_singles + local trace_alternatives=trace_baseinit and trace_alternatives + local trace_ligatures=trace_baseinit and trace_ligatures + if not changed then + changed={} + tfmdata.changed=changed + end + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + if kind=="gsub_single" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + if unicode~=data then + changed[unicode]=data + end + if trace_singles then + report_substitution(feature,sequence,descriptions,unicode,data) + end + end + end + elseif kind=="gsub_alternate" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + local replacement=data[alternate] + if replacement then + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") + end + elseif defaultalt=="first" then + replacement=data[1] + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + elseif defaultalt=="last" then + replacement=data[#data] + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + else + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") + end + end + end + end + elseif kind=="gsub_ligature" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + ligatures[#ligatures+1]={ unicode,data,"" } + if trace_ligatures then + report_ligature(feature,sequence,descriptions,unicode,data) + end + end + end + end + end + local nofligatures=#ligatures + if nofligatures>0 then + local characters=tfmdata.characters + local present={} + local done=trace_baseinit and trace_ligatures and {} + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + make_1(present,tree,"ctx_"..unicode) + end + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + local lookupname=ligature[3] + make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) + end + end +end +local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist) + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local properties=tfmdata.properties + local traceindeed=trace_baseinit and trace_kerns + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + local format=sequence.format + if kind=="gpos_pair" then + for i=1,#steps do + local step=steps[i] + local format=step.format + if format=="kern" or format=="move" then + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + if not kerns then + kerns={} + character.kerns=kerns + end + if traceindeed then + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end + else + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + end + end + end + end + else + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + for otherunicode,kern in next,data do + local other=kern[2] + if other==true or (not other and not (kerns and kerns[otherunicode])) then + local kern=kern[1] + if kern==true then + elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then + else + kern=kern[3] + if kern~=0 then + if kerns then + kerns[otherunicode]=kern + else + kerns={ [otherunicode]=kern } + character.kerns=kerns + end + if traceindeed then + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end + end + end + end + end + end + end + end + end +end +local function initializehashes(tfmdata) +end +local function checkmathreplacements(tfmdata,fullname,fixitalics) + if tfmdata.mathparameters then + local characters=tfmdata.characters + local changed=tfmdata.changed + if next(changed) then + if trace_preparing or trace_baseinit then + report_prepare("checking math replacements for %a",fullname) + end + for unicode,replacement in next,changed do + local u=characters[unicode] + local r=characters[replacement] + if u and r then + local n=u.next + local v=u.vert_variants + local h=u.horiz_variants + if fixitalics then + local ui=u.italic + if ui and not r.italic then + if trace_preparing then + report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) + end + r.italic=ui + end + end + if n and not r.next then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) + end + r.next=n + end + if v and not r.vert_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) + end + r.vert_variants=v + end + if h and not r.horiz_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) + end + r.horiz_variants=h + end + else + if trace_preparing then + report_prepare("error replacing %C by %U",unicode,replacement) + end + end + end + end + end +end +local function featuresinitializer(tfmdata,value) + if true then + local starttime=trace_preparing and os.clock() + local features=tfmdata.shared.features + local fullname=tfmdata.properties.fullname or "?" + if features then + initializehashes(tfmdata) + local collectlookups=otf.collectlookups + local rawdata=tfmdata.shared.rawdata + local properties=tfmdata.properties + local script=properties.script + local language=properties.language + local rawresources=rawdata.resources + local rawfeatures=rawresources and rawresources.features + local basesubstitutions=rawfeatures and rawfeatures.gsub + local basepositionings=rawfeatures and rawfeatures.gpos + local substitutionsdone=false + local positioningsdone=false + if basesubstitutions or basepositionings then + local sequences=tfmdata.resources.sequences + for s=1,#sequences do + local sequence=sequences[s] + local sfeatures=sequence.features + if sfeatures then + local order=sequence.order + if order then + for i=1,#order do + local feature=order[i] + local value=features[feature] + if value then + local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) + if not validlookups then + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) + end + preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + substitutionsdone=true + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) + end + preparepositionings(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + positioningsdone=true + end + end + end + end + end + end + end + if substitutionsdone then + checkmathreplacements(tfmdata,fullname,features.fixitalics) + end + registerbasehash(tfmdata) + end + if trace_preparing then + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) + end + end +end +registerotffeature { + name="features", + description="features", + default=true, + initializers={ + base=featuresinitializer, + } +} +otf.basemodeinitializer=featuresinitializer + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj” 8de59cb9b043e5f73c6b9f7cc8f6978e] --- + +if not modules then modules={} end modules ['font-otj']={ + version=1.001, + optimize=true, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +if not nodes.properties then return end +local next,rawget,tonumber=next,rawget,tonumber +local fastcopy=table.fastcopy +local registertracker=trackers.register +local registerdirective=directives.register +local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) +local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) +local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) +local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) +local report_injections=logs.reporter("fonts","injections") +local report_spaces=logs.reporter("fonts","spaces") +local attributes,nodes,node=attributes,nodes,node +fonts=fonts +local hashes=fonts.hashes +local fontdata=hashes.identifiers +local fontmarks=hashes.marks +nodes.injections=nodes.injections or {} +local injections=nodes.injections +local tracers=nodes.tracers +local setcolor=tracers and tracers.colors.set +local resetcolor=tracers and tracers.colors.reset +local nodecodes=nodes.nodecodes +local glyph_code=nodecodes.glyph +local disc_code=nodecodes.disc +local kern_code=nodecodes.kern +local glue_code=nodecodes.glue +local nuts=nodes.nuts +local nodepool=nuts.pool +local tonode=nuts.tonode +local tonut=nuts.tonut +local setfield=nuts.setfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getfont=nuts.getfont +local getchar=nuts.getchar +local getoffsets=nuts.getoffsets +local getboth=nuts.getboth +local getdisc=nuts.getdisc +local setdisc=nuts.setdisc +local setoffsets=nuts.setoffsets +local ischar=nuts.ischar +local getkern=nuts.getkern +local setkern=nuts.setkern +local setlink=nuts.setlink +local setwidth=nuts.setwidth +local getwidth=nuts.getwidth +local nextchar=nuts.traversers.char +local nextglue=nuts.traversers.glue +local insert_node_before=nuts.insert_before +local insert_node_after=nuts.insert_after +local properties=nodes.properties.data +local fontkern=nuts.pool and nuts.pool.fontkern +local italickern=nuts.pool and nuts.pool.italickern +local useitalickerns=false +directives.register("fonts.injections.useitalics",function(v) + if v then + report_injections("using italics for space kerns (tracing only)") + end + useitalickerns=v +end) +if not fontkern then + local thekern=nuts.new("kern",0) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + fontkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end +if not italickern then + local thekern=nuts.new("kern",3) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + italickern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end +function injections.installnewkern() end +local nofregisteredkerns=0 +local nofregisteredpositions=0 +local nofregisteredmarks=0 +local nofregisteredcursives=0 +local keepregisteredcounts=false +function injections.keepcounts() + keepregisteredcounts=true +end +function injections.resetcounts() + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + keepregisteredcounts=false +end +function injections.reset(n) + local p=rawget(properties,n) + if p then + p.injections=false + else + properties[n]=false + end +end +function injections.copy(target,source) + local sp=rawget(properties,source) + if sp then + local tp=rawget(properties,target) + local si=sp.injections + if si then + si=fastcopy(si) + if tp then + tp.injections=si + else + properties[target]={ + injections=si, + } + end + elseif tp then + tp.injections=false + else + properties[target]={ injections={} } + end + else + local tp=rawget(properties,target) + if tp then + tp.injections=false + else + properties[target]=false + end + end +end +function injections.setligaindex(n,index) + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + i.ligaindex=index + else + p.injections={ + ligaindex=index + } + end + else + properties[n]={ + injections={ + ligaindex=index + } + } + end +end +function injections.getligaindex(n,default) + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + return i.ligaindex or default + end + end + return default +end +function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag) + local dx=factor*(exit[1]-entry[1]) + local dy=-factor*(exit[2]-entry[2]) + local ws=tfmstart.width + local wn=tfmnext.width + nofregisteredcursives=nofregisteredcursives+1 + if rlmode<0 then + dx=-(dx+wn) + else + dx=dx-ws + end + if dx==0 then + dx=0 + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + i.cursiveanchor=true + else + p.injections={ + cursiveanchor=true, + } + end + else + properties[start]={ + injections={ + cursiveanchor=true, + }, + } + end + local p=rawget(properties,nxt) + if p then + local i=p.injections + if i then + i.cursivex=dx + i.cursivey=dy + else + p.injections={ + cursivex=dx, + cursivey=dy, + } + end + else + properties[nxt]={ + injections={ + cursivex=dx, + cursivey=dy, + }, + } + end + return dx,dy,nofregisteredcursives +end +function injections.setposition(kind,current,factor,rlmode,spec,injection) + local x=factor*(spec[1] or 0) + local y=factor*(spec[2] or 0) + local w=factor*(spec[3] or 0) + local h=factor*(spec[4] or 0) + if x~=0 or w~=0 or y~=0 or h~=0 then + local yoffset=y-h + local leftkern=x + local rightkern=w-x + if leftkern~=0 or rightkern~=0 or yoffset~=0 then + nofregisteredpositions=nofregisteredpositions+1 + if rlmode and rlmode<0 then + leftkern,rightkern=rightkern,leftkern + end + if not injection then + injection="injections" + end + local p=rawget(properties,current) + if p then + local i=p[injection] + if i then + if leftkern~=0 then + i.leftkern=(i.leftkern or 0)+leftkern + end + if rightkern~=0 then + i.rightkern=(i.rightkern or 0)+rightkern + end + if yoffset~=0 then + i.yoffset=(i.yoffset or 0)+yoffset + end + elseif leftkern~=0 or rightkern~=0 then + p[injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + } + else + p[injection]={ + yoffset=yoffset, + } + end + elseif leftkern~=0 or rightkern~=0 then + properties[current]={ + [injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + }, + } + else + properties[current]={ + [injection]={ + yoffset=yoffset, + }, + } + end + return x,y,w,h,nofregisteredpositions + end + end + return x,y,w,h +end +function injections.setkern(current,factor,rlmode,x,injection) + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" + end + if p then + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, + } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, + } + end + return dx,nofregisteredkerns + else + return 0,0 + end +end +function injections.setmove(current,factor,rlmode,x,injection) + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" + end + if rlmode and rlmode<0 then + if p then + local i=p[injection] + if i then + i.rightkern=dx+(i.rightkern or 0) + else + p[injection]={ + rightkern=dx, + } + end + else + properties[current]={ + [injection]={ + rightkern=dx, + }, + } + end + else + if p then + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, + } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, + } + end + end + return dx,nofregisteredkerns + else + return 0,0 + end +end +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) + local dx=factor*(ba[1]-ma[1]) + local dy=factor*(ba[2]-ma[2]) + nofregisteredmarks=nofregisteredmarks+1 + if rlmode>=0 then + dx=tfmbase.width-dx + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + if i.markmark then + else + i.markx=dx + i.marky=dy + i.markdir=rlmode or 0 + i.markbase=nofregisteredmarks + i.markbasenode=base + i.markmark=mkmk + i.checkmark=checkmark + end + else + p.injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + } + end + else + properties[start]={ + injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + }, + } + end + return dx,dy,nofregisteredmarks +end +local function dir(n) + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" +end +local function showchar(n,nested) + local char=getchar(n) + report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) +end +local function show(n,what,nested,symbol) + if n then + local p=rawget(properties,n) + if p then + local i=p[what] + if i then + local leftkern=i.leftkern or 0 + local rightkern=i.rightkern or 0 + local yoffset=i.yoffset or 0 + local markx=i.markx or 0 + local marky=i.marky or 0 + local markdir=i.markdir or 0 + local markbase=i.markbase or 0 + local cursivex=i.cursivex or 0 + local cursivey=i.cursivey or 0 + local ligaindex=i.ligaindex or 0 + local cursbase=i.cursiveanchor + local margin=nested and 4 or 2 + if rightkern~=0 or yoffset~=0 then + report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) + elseif leftkern~=0 then + report_injections("%w%s kern: dx %p",margin,symbol,leftkern) + end + if markx~=0 or marky~=0 or markbase~=0 then + report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") + end + if cursivex~=0 or cursivey~=0 then + if cursbase then + report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) + else + report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) + end + elseif cursbase then + report_injections("%w%s curs: base",margin,symbol) + end + if ligaindex~=0 then + report_injections("%w%s liga: index %i",margin,symbol,ligaindex) + end + end + end + end +end +local function showsub(n,what,where) + report_injections("begin subrun: %s",where) + for n in nextchar,n do + showchar(n,where) + show(n,what,where," ") + end + report_injections("end subrun") +end +local function trace(head,where) + report_injections() + report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", + where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) + local n=head + while n do + local id=getid(n) + if id==glyph_code then + showchar(n) + show(n,"injections",false," ") + show(n,"preinjections",false,"<") + show(n,"postinjections",false,">") + show(n,"replaceinjections",false,"=") + show(n,"emptyinjections",false,"*") + elseif id==disc_code then + local pre,post,replace=getdisc(n) + if pre then + showsub(pre,"preinjections","pre") + end + if post then + showsub(post,"postinjections","post") + end + if replace then + showsub(replace,"replaceinjections","replace") + end + show(n,"emptyinjections",false,"*") + end + n=getnext(n) + end + report_injections("end run") +end +local function show_result(head) + local current=head + local skipping=false + while current do + local id=getid(current) + if id==glyph_code then + local w=getwidth(current) + local x,y=getoffsets(current) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) + skipping=false + elseif id==kern_code then + report_injections("kern: %p",getkern(current)) + skipping=false + elseif not skipping then + report_injections() + skipping=true + end + current=getnext(current) + end + report_injections() +end +local function inject_kerns_only(head,where) + if trace_injections then + trace(head,"kerns") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + if prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + prevdisc=nil + elseif char==false then + prevdisc=nil + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevdisc=current + else + prevdisc=nil + end + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + end + if trace_injections then + show_result(head) + end + return head +end +local function inject_positions_only(head,where) + if trace_injections then + trace(head,"positions") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + elseif prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if rightkern and rightkern~=0 then + if next and getid(next)==glue_code then + if useitalickerns then + insert_node_after(head,current,italickern(rightkern)) + else + setwidth(next,getwidth(next)+rightkern) + end + else + insert_node_after(head,current,fontkern(rightkern)) + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + replace=fontkern(rightkern) + done=true + end + end + end + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current + else + prevglyph=nil + prevdisc=nil + end + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredpositions=0 + end + if trace_injections then + show_result(head) + end + return head +end +local function showoffset(n,flag) + local x,y=getoffsets(n) + if x~=0 or y~=0 then + setcolor(n,"darkgray") + end +end +local function inject_everything(head,where) + if trace_injections then + trace(head,"everything") + end + local hascursives=nofregisteredcursives>0 + local hasmarks=nofregisteredmarks>0 + local current=head + local last=nil + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + local cursiveanchor=nil + local minc=0 + local maxc=0 + local glyphs={} + local marks={} + local nofmarks=0 + local function processmark(p,n,pn) + local px,py=getoffsets(p) + local nx,ny=getoffsets(n) + local ox=0 + local rightkern=nil + local pp=rawget(properties,p) + if pp then + pp=pp.injections + if pp then + rightkern=pp.rightkern + end + end + local markdir=pn.markdir + if rightkern then + ox=px-(pn.markx or 0)-rightkern + if markdir and markdir<0 then + if not pn.markmark then + ox=ox+(pn.leftkern or 0) + end + else + if false then + local leftkern=pp.leftkern + if leftkern then + ox=ox-leftkern + end + end + end + else + ox=px-(pn.markx or 0) + if markdir and markdir<0 then + if not pn.markmark then + local leftkern=pn.leftkern + if leftkern then + ox=ox+leftkern + end + end + end + if pn.checkmark then + local wn=getwidth(n) + if wn and wn~=0 then + wn=wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + insert_node_before(n,n,fontkern(-wn)) + insert_node_after(n,n,fontkern(-wn)) + end + end + end + local oy=ny+py+(pn.marky or 0) + if not pn.markmark then + local yoffset=pn.yoffset + if yoffset then + oy=oy+yoffset + end + end + setoffsets(n,ox,oy) + if trace_marks then + showoffset(n,true) + end + end + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local pm=i.markbasenode + if pm then + nofmarks=nofmarks+1 + marks[nofmarks]=current + else + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + if hascursives then + local cursivex=i.cursivex + if cursivex then + if cursiveanchor then + if cursivex~=0 then + i.leftkern=(i.leftkern or 0)+cursivex + end + if maxc==0 then + minc=1 + maxc=1 + glyphs[1]=cursiveanchor + else + maxc=maxc+1 + glyphs[maxc]=cursiveanchor + end + properties[cursiveanchor].cursivedy=i.cursivey + last=current + else + maxc=0 + end + elseif maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + cursiveanchor=nil + end + if i.cursiveanchor then + cursiveanchor=current + else + if maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + end + cursiveanchor=nil + end + end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + elseif prev and getid(prev)==glue_code then + if useitalickerns then + head=insert_node_before(head,current,italickern(leftkern)) + else + setwidth(prev,getwidth(prev)+leftkern) + end + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if rightkern and rightkern~=0 then + if next and getid(next)==glue_code then + if useitalickerns then + insert_node_after(head,current,italickern(rightkern)) + else + setwidth(next,getwidth(next)+rightkern) + end + else + insert_node_after(head,current,fontkern(rightkern)) + end + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + replace=fontkern(rightkern) + done=true + end + end + end + end + end + if prevdisc then + if p then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end + end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end + end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + else + if hascursives and maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + local xi,yi=getoffsets(ti) + setoffsets(ti,xi,yi+ny) + end + maxc=0 + cursiveanchor=nil + end + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current + else + prevglyph=nil + prevdisc=nil + end + prev=current + current=next + end + if hascursives and maxc>0 then + local nx,ny=getoffsets(last) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + end + if nofmarks>0 then + for i=1,nofmarks do + local m=marks[i] + local p=rawget(properties,m) + local i=p.injections + local b=i.markbasenode + processmark(b,m,i) + end + elseif hasmarks then + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + end + if trace_injections then + show_result(head) + end + return head +end +local triggers=false +function nodes.injections.setspacekerns(font,sequence) + if triggers then + triggers[font]=sequence + else + triggers={ [font]=sequence } + end +end +local getthreshold +if context then + local threshold=1 + local parameters=fonts.hashes.parameters + directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) + getthreshold=function(font) + local p=parameters[font] + local f=p.factor + local s=p.spacing + local t=threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +else + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end +end +injections.getthreshold=getthreshold +function injections.isspace(n,threshold,id) + if (id or getid(n))==glue_code then + local w=getwidth(n) + if threshold and w>threshold then + return 32 + end + end +end +local getspaceboth=getboth +function injections.installgetspaceboth(gb) + getspaceboth=gb or getboth +end +local function injectspaces(head) + if not triggers then + return head + end + local lastfont=nil + local spacekerns=nil + local leftkerns=nil + local rightkerns=nil + local factor=0 + local threshold=0 + local leftkern=false + local rightkern=false + local function updatefont(font,trig) + leftkerns=trig.left + rightkerns=trig.right + lastfont=font + threshold, + factor=getthreshold(font) + end + for n in nextglue,head do + local prev,next=getspaceboth(n) + local prevchar=prev and ischar(prev) + local nextchar=next and ischar(next) + if nextchar then + local font=getfont(next) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if rightkerns then + rightkern=rightkerns[nextchar] + end + end + end + if prevchar then + local font=getfont(prev) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if leftkerns then + leftkern=leftkerns[prevchar] + end + end + end + if leftkern then + local old=getwidth(n) + if old>threshold then + if rightkern then + if useitalickerns then + local lnew=leftkern*factor + local rnew=rightkern*factor + if trace_spaces then + report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) + end + head=insert_node_before(head,n,italickern(lnew)) + insert_node_after(head,n,italickern(rnew)) + else + local new=old+(leftkern+rightkern)*factor + if trace_spaces then + report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) + end + setwidth(n,new) + end + rightkern=false + else + if useitalickerns then + local new=leftkern*factor + if trace_spaces then + report_spaces("%C [%p + %p]",prevchar,old,new) + end + insert_node_after(head,n,italickern(new)) + else + local new=old+leftkern*factor + if trace_spaces then + report_spaces("%C [%p -> %p]",prevchar,old,new) + end + setwidth(n,new) + end + end + end + leftkern=false + elseif rightkern then + local old=getwidth(n) + if old>threshold then + if useitalickerns then + local new=rightkern*factor + if trace_spaces then + report_spaces("[%p + %p] %C",old,new,nextchar) + end + insert_node_after(head,n,italickern(new)) + else + local new=old+rightkern*factor + if trace_spaces then + report_spaces("[%p -> %p] %C",old,new,nextchar) + end + setwidth(n,new) + end + else + end + rightkern=false + end + end + triggers=false + return head +end +function injections.handler(head,where) + if triggers then + head=injectspaces(head) + end + if nofregisteredmarks>0 or nofregisteredcursives>0 then + if trace_injections then + report_injections("injection variant %a","everything") + end + return inject_everything(head,where) + elseif nofregisteredpositions>0 then + if trace_injections then + report_injections("injection variant %a","positions") + end + return inject_positions_only(head,where) + elseif nofregisteredkerns>0 then + if trace_injections then + report_injections("injection variant %a","kerns") + end + return inject_kerns_only(head,where) + else + return head + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota” ad1d5de06400f88829509e1f3ff2b473] --- + +if not modules then modules={} end modules ['font-ota']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local type=type +local setmetatableindex=table.setmetatableindex +if not trackers then trackers={ register=function() end } end +local fonts,nodes,node=fonts,nodes,node +local allocate=utilities.storage.allocate +local otf=fonts.handlers.otf +local analyzers=fonts.analyzers +local initializers=allocate() +local methods=allocate() +analyzers.initializers=initializers +analyzers.methods=methods +local nuts=nodes.nuts +local tonut=nuts.tonut +local getnext=nuts.getnext +local getprev=nuts.getprev +local getprev=nuts.getprev +local getprop=nuts.getprop +local setprop=nuts.setprop +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local ischar=nuts.ischar +local end_of_math=nuts.end_of_math +local nodecodes=nodes.nodecodes +local disc_code=nodecodes.disc +local math_code=nodecodes.math +local fontdata=fonts.hashes.identifiers +local categories=characters and characters.categories or {} +local chardata=characters and characters.data +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local setstate=nuts.setstate +local getstate=nuts.getstate +if not setstate or not getstate then + setstate=function(n,v) + setprop(n,"state",v) + end + getstate=function(n,v) + local s=getprop(n,"state") + if v then + return s==v + else + return s + end + end + nuts.setstate=setstate + nuts.getstate=getstate +end +local s_init=1 local s_rphf=7 +local s_medi=2 local s_half=8 +local s_fina=3 local s_pref=9 +local s_isol=4 local s_blwf=10 +local s_mark=5 local s_pstf=11 +local s_rest=6 +local states=allocate { + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + mark=s_mark, + rest=s_rest, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, +} +local features=allocate { + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, +} +analyzers.states=states +analyzers.features=features +analyzers.useunicodemarks=false +function analyzers.setstate(head,font) + local useunicodemarks=analyzers.useunicodemarks + local tfmdata=fontdata[font] + local descriptions=tfmdata.descriptions + local first,last,current,n,done=nil,nil,head,0,false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + done=true + local d=descriptions[char] + if d then + if d.class=="mark" then + done=true + setstate(current,s_mark) + elseif useunicodemarks and categories[char]=="mn" then + done=true + setstate(current,s_mark) + elseif n==0 then + first,last,n=current,current,1 + setstate(current,s_init) + else + last,n=current,n+1 + setstate(current,s_medi) + end + else + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + end + elseif char==false then + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + elseif id==disc_code then + setstate(current,s_medi) + last=current + else + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if first and first==last then + setstate(last,s_isol) + elseif last then + setstate(last,s_fina) + end + return head,done +end +local function analyzeinitializer(tfmdata,value) + local script,language=otf.scriptandlanguage(tfmdata) + local action=initializers[script] + if not action then + elseif type(action)=="function" then + return action(tfmdata,value) + else + local action=action[language] + if action then + return action(tfmdata,value) + end + end +end +local function analyzeprocessor(head,font,attr) + local tfmdata=fontdata[font] + local script,language=otf.scriptandlanguage(tfmdata,attr) + local action=methods[script] + if not action then + elseif type(action)=="function" then + return action(head,font,attr) + else + action=action[language] + if action then + return action(head,font,attr) + end + end + return head,false +end +registerotffeature { + name="analyze", + description="analysis of character classes", + default=true, + initializers={ + node=analyzeinitializer, + }, + processors={ + position=1, + node=analyzeprocessor, + } +} +methods.latn=analyzers.setstate +local arab_warned={} +local function warning(current,what) + local char=getchar(current) + if not arab_warned[char] then + log.report("analyze","arab: character %C has no %a class",char,what) + arab_warned[char]=true + end +end +local mappers=allocate { + l=s_init, + d=s_medi, + c=s_medi, + r=s_fina, + u=s_isol, +} +local classifiers=characters.classifiers +if not classifiers then + local f_arabic,l_arabic=characters.blockrange("arabic") + local f_syriac,l_syriac=characters.blockrange("syriac") + local f_mandiac,l_mandiac=characters.blockrange("mandiac") + local f_nko,l_nko=characters.blockrange("nko") + local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") + classifiers=setmetatableindex(function(t,k) + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local arabic=c.arabic + if arabic then + v=mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + v=false + end + elseif (k>=f_arabic and k<=l_arabic) or + (k>=f_syriac and k<=l_syriac) or + (k>=f_mandiac and k<=l_mandiac) or + (k>=f_nko and k<=l_nko) or + (k>=f_ext_a and k<=l_ext_a) then + if categories[k]=="mn" then + v=s_mark + else + v=s_rest + end + end + end + t[k]=v + return v + end + end) + characters.classifiers=classifiers +end +function methods.arab(head,font,attr) + local first,last,c_first,c_last + local current=head + local done=false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + done=true + local classifier=classifiers[char] + if not classifier then + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + elseif classifier==s_mark then + setstate(current,s_mark) + elseif classifier==s_isol then + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + setstate(current,s_isol) + elseif classifier==s_medi then + if first then + last=current + c_last=classifier + setstate(current,s_medi) + else + setstate(current,s_init) + first=current + c_first=classifier + end + elseif classifier==s_fina then + if last then + if getstate(last)~=s_init then + setstate(last,s_medi) + end + setstate(current,s_fina) + first,last=nil,nil + elseif first then + setstate(current,s_fina) + first=nil + else + setstate(current,s_isol) + end + else + setstate(current,s_rest) + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + end + else + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + first=nil + end + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if last then + if c_last==s_medi or c_last==s_fina then + setstate(last,s_fina) + else + warning(last,"fina") + setstate(last,s_error) + end + elseif first then + if c_first==s_medi or c_first==s_fina then + setstate(first,s_isol) + else + warning(first,"isol") + setstate(first,s_error) + end + end + return head,done +end +methods.syrc=methods.arab +methods.mand=methods.arab +methods.nko=methods.arab +do + local joining=setmetatableindex(function(t,k) + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local mongolian=c.mongolian + v=mongolian + end + t[k]=v + return v + end + end) + function methods.mong(head,font,attr) + local first,last + local current=head + local done=false + local prevjoin=nil + local prestate=nil + current=tonut(current) + local function wrapup() + if last then + if last~=first then + local s=getstate(last) + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + end + last=nil + first=nil + prevjoin=nil + prestate=nil + end + end + while current do + local char,id=ischar(current,font) + if char and not getstate(current) then + local currjoin=joining[char] + done=true + if not last then + setstate(current,s_isol) + prevjoin=currjoin + first=current + last=current + prevstate=s_isol + elseif currjoin=="t" then + last=current + elseif prevjoin=="d" or prevjoin=="jc" or prevjoin=="l" then + if currjoin=="d" or prevjoin=="jc" or prevjoin=="r" then + local s=getstate(last) + if s==s_isol then + setstate(last,s_init) + elseif s==s_fina then + setstate(last,s_medi) + end + setstate(current,s_fina) + prevstate=s_fina + elseif prevjoin=="nj" or prevjoin=="l" then + local s=getstate(last) + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + setstate(current,s_isol) + prevstate=s_isol + end + prevjoin=currjoin + last=current + elseif prevjoin=="nj" or prevjoin=="r" then + if s==s_medi then + setstate(last,s_fina) + elseif s==s_init then + setstate(last,s_isol) + end + setstate(current,s_isol) + prevjoin=currjoin + prevstate=s_isol + last=current + elseif last then + wrapup() + end + else + if last then + wrapup() + end + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if last then + wrapup() + end + return head,done + end +end +directives.register("otf.analyze.useunicodemarks",function(v) + analyzers.useunicodemarks=v +end) + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots” 91c79619c386e4a96954f3115f398b94] --- + +if not modules then modules={} end modules ['font-ots']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local type,next,tonumber=type,next,tonumber +local random=math.random +local formatters=string.formatters +local insert=table.insert +local registertracker=trackers.register +local logs=logs +local trackers=trackers +local nodes=nodes +local attributes=attributes +local fonts=fonts +local otf=fonts.handlers.otf +local tracers=nodes.tracers +local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) +local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) +local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) +local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) +local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) +local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) +local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) +local trace_details=false registertracker("otf.details",function(v) trace_details=v end) +local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) +local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) +local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) +local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) +local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) +local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) +local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) +local forcediscretionaries=false +local forcepairadvance=false +directives.register("otf.forcediscretionaries",function(v) + forcediscretionaries=v +end) +directives.register("otf.forcepairadvance",function(v) + forcepairadvance=v +end) +local report_direct=logs.reporter("fonts","otf direct") +local report_subchain=logs.reporter("fonts","otf subchain") +local report_chain=logs.reporter("fonts","otf chain") +local report_process=logs.reporter("fonts","otf process") +local report_warning=logs.reporter("fonts","otf warning") +local report_run=logs.reporter("fonts","otf run") +registertracker("otf.substitutions","otf.singles","otf.multiples","otf.alternatives","otf.ligatures") +registertracker("otf.positions","otf.marks","otf.kerns","otf.cursive") +registertracker("otf.actions","otf.substitutions","otf.positions") +registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") +registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") +local nuts=nodes.nuts +local getnext=nuts.getnext +local setnext=nuts.setnext +local getprev=nuts.getprev +local setprev=nuts.setprev +local getboth=nuts.getboth +local setboth=nuts.setboth +local getid=nuts.getid +local getstate=nuts.getstate +local getsubtype=nuts.getsubtype +local setsubtype=nuts.setsubtype +local getchar=nuts.getchar +local setchar=nuts.setchar +local getdisc=nuts.getdisc +local setdisc=nuts.setdisc +local getreplace=nuts.getreplace +local setlink=nuts.setlink +local getwidth=nuts.getwidth +local getattr=nuts.getattr +local getglyphdata=nuts.getglyphdata +local copy_no_components=nuts.copy_no_components +local copy_only_glyphs=nuts.copy_only_glyphs +local count_components=nuts.count_components +local set_components=nuts.set_components +local get_components=nuts.get_components +local flush_components=nuts.flush_components +local ischar=nuts.ischar +local usesfont=nuts.uses_font +local insert_node_after=nuts.insert_after +local copy_node=nuts.copy +local copy_node_list=nuts.copy_list +local remove_node=nuts.remove +local find_node_tail=nuts.tail +local flush_node_list=nuts.flush_list +local flush_node=nuts.flush_node +local end_of_math=nuts.end_of_math +local start_of_par=nuts.start_of_par +local setmetatable=setmetatable +local setmetatableindex=table.setmetatableindex +local nextnode=nuts.traversers.node +local nodecodes=nodes.nodecodes +local glyphcodes=nodes.glyphcodes +local disccodes=nodes.disccodes +local glyph_code=nodecodes.glyph +local glue_code=nodecodes.glue +local disc_code=nodecodes.disc +local math_code=nodecodes.math +local dir_code=nodecodes.dir +local par_code=nodecodes.par +local lefttoright_code=nodes.dirvalues.lefttoright +local righttoleft_code=nodes.dirvalues.righttoleft +local discretionarydisc_code=disccodes.discretionary +local ligatureglyph_code=glyphcodes.ligature +local a_noligature=attributes.private("noligature") +local injections=nodes.injections +local setmark=injections.setmark +local setcursive=injections.setcursive +local setkern=injections.setkern +local setmove=injections.setmove +local setposition=injections.setposition +local resetinjection=injections.reset +local copyinjection=injections.copy +local setligaindex=injections.setligaindex +local getligaindex=injections.getligaindex +local fontdata=fonts.hashes.identifiers +local fontfeatures=fonts.hashes.features +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local onetimemessage=fonts.loggers.onetimemessage or function() end +local getrandom=utilities and utilities.randomizer and utilities.randomizer.get +otf.defaultnodealternate="none" +local tfmdata=false +local characters=false +local descriptions=false +local marks=false +local classes=false +local currentfont=false +local factor=0 +local threshold=0 +local checkmarks=false +local discs=false +local spaces=false +local sweepnode=nil +local sweephead={} +local notmatchpre={} +local notmatchpost={} +local notmatchreplace={} +local handlers={} +local isspace=injections.isspace +local getthreshold=injections.getthreshold +local checkstep=(tracers and tracers.steppers.check) or function() end +local registerstep=(tracers and tracers.steppers.register) or function() end +local registermessage=(tracers and tracers.steppers.message) or function() end +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_direct(...) +end +local function logwarning(...) + report_direct(...) +end +local gref do + local f_unicode=formatters["U+%X"] + local f_uniname=formatters["U+%X (%s)"] + local f_unilist=formatters["% t"] + gref=function(n) + if type(n)=="number" then + local description=descriptions[n] + local name=description and description.name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local t={} + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + local di=descriptions[ni] + local nn=di and di.name + if nn then + t[#t+1]=f_uniname(ni,nn) + else + t[#t+1]=f_unicode(ni) + end + end + end + return f_unilist(t) + else + return "" + end + end +end +local function cref(dataset,sequence,index) + if not dataset then + return "no valid dataset" + end + local merged=sequence.merged and "merged " or "" + if index then + return formatters["feature %a, type %a, %schain lookup %a, index %a"]( + dataset[4],sequence.type,merged,sequence.name,index) + else + return formatters["feature %a, type %a, %schain lookup %a"]( + dataset[4],sequence.type,merged,sequence.name) + end +end +local function pref(dataset,sequence) + return formatters["feature %a, type %a, %slookup %a"]( + dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) +end +local function mref(rlmode) + if not rlmode or rlmode>=0 then + return "l2r" + else + return "r2l" + end +end +local function flattendisk(head,disc) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prev,next=getboth(disc) + local ishead=head==disc + setdisc(disc) + flush_node(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then + if replace then + if next then + setlink(replacetail,next) + end + return replace,replace + elseif next then + return next,next + else + end + else + if replace then + if next then + setlink(replacetail,next) + end + setlink(prev,replace) + return head,replace + else + setlink(prev,next) + return head,next + end + end +end +local function appenddisc(disc,list) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local posthead=list + local replacehead=copy_node_list(list) + if post then + setlink(posttail,posthead) + else + post=posthead + end + if replace then + setlink(replacetail,replacehead) + else + replace=replacehead + end + setdisc(disc,pre,post,replace) +end +local function markstoligature(head,start,stop,char) + if start==stop and getchar(start)==char then + return head,start + else + local prev=getprev(start) + local next=getnext(stop) + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) + if head==start then + head=base + end + resetinjection(base) + setchar(base,char) + setsubtype(base,ligatureglyph_code) + set_components(base,start) + setlink(prev,base,next) + flush_components(start) + return head,base + end +end +local no_left_ligature_code=1 +local no_right_ligature_code=2 +local no_left_kern_code=4 +local no_right_kern_code=8 +local has_glyph_option=node.direct.has_glyph_option or function(n,c) + if c==no_left_ligature_code or c==no_right_ligature_code then + return getattr(n,a_noligature)==1 + else + return false + end +end +local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) + if has_glyph_option(start,no_right_ligature_code) then + return head,start + end + if start==stop and getchar(start)==char then + resetinjection(start) + setchar(start,char) + return head,start + end + local prev=getprev(start) + local next=getnext(stop) + local comp=start + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) + if start==head then + head=base + end + resetinjection(base) + setchar(base,char) + setsubtype(base,ligatureglyph_code) + set_components(base,comp) + setlink(prev,base,next) + if not discfound then + local deletemarks=not skiphash or hasmarks + local components=start + local baseindex=0 + local componentindex=0 + local head=base + local current=base + while start do + local char=getchar(start) + if not marks[char] then + baseindex=baseindex+componentindex + componentindex=count_components(start,marks) + elseif not deletemarks then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) + end + local n=copy_node(start) + copyinjection(n,start) + head,current=insert_node_after(head,current,n) + elseif trace_marks then + logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char)) + end + start=getnext(start) + end + local start=getnext(current) + while start do + local char=ischar(start) + if char then + if marks[char] then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) + end + start=getnext(start) + else + break + end + else + break + end + end + flush_components(components) + else + local discprev,discnext=getboth(discfound) + if discprev and discnext then + local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) + if not replace then + local prev=getprev(base) + local copied=copy_only_glyphs(comp) + if pre then + setlink(discprev,pre) + else + setnext(discprev) + end + pre=comp + if post then + setlink(posttail,discnext) + setprev(post) + else + post=discnext + setprev(discnext) + end + setlink(prev,discfound,next) + setboth(base) + set_components(base,copied) + replace=base + if forcediscretionaries then + setdisc(discfound,pre,post,replace,discretionarydisc_code) + else + setdisc(discfound,pre,post,replace) + end + base=prev + end + end + end + return head,base +end +local function multiple_glyphs(head,start,multiple,skiphash,what,stop) + local nofmultiples=#multiple + if nofmultiples>0 then + resetinjection(start) + setchar(start,multiple[1]) + if nofmultiples>1 then + local sn=getnext(start) + for k=2,nofmultiples do + local n=copy_node(start) + resetinjection(n) + setchar(n,multiple[k]) + insert_node_after(head,start,n) + start=n + end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end + end + return head,start,true + else + if trace_multiples then + logprocess("no multiple for %s",gref(getchar(start))) + end + return head,start,false + end +end +local function get_alternative_glyph(start,alternatives,value) + local n=#alternatives + if n==1 then + return alternatives[1],trace_alternatives and "1 (only one present)" + elseif value=="random" then + local r=getrandom and getrandom("glyph",1,n) or random(1,n) + return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) + elseif value=="first" then + return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) + elseif value=="last" then + return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) + end + value=value==true and 1 or tonumber(value) + if type(value)~="number" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + end + if value>n then + local defaultalt=otf.defaultnodealternate + if defaultalt=="first" then + return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + elseif defaultalt=="last" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) + else + return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") + end + elseif value==0 then + return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + elseif value<1 then + return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) + else + return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) + end +end +function handlers.gsub_single(head,start,dataset,sequence,replacement) + if trace_singles then + logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) + end + resetinjection(start) + setchar(start,replacement) + return head,start,true +end +function handlers.gsub_alternate(head,start,dataset,sequence,alternative) + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local choice,comment=get_alternative_glyph(start,alternative,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) + end + end + return head,start,true +end +function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash) + if trace_multiples then + logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) + end + return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) +end +function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) + local current=getnext(start) + if not current then + return head,start,false,nil + end + local stop=nil + local startchar=getchar(start) + if skiphash and skiphash[startchar] then + while current do + local char=ischar(current,currentfont) + if char then + local lg=ligature[char] + if lg then + stop=current + ligature=lg + current=getnext(current) + else + break + end + else + break + end + end + if stop then + local lig=ligature.ligature + if lig then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=markstoligature(head,start,stop,lig) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) + else + head,start=markstoligature(head,start,stop,lig) + end + return head,start,true,false + else + end + end + else + local discfound=false + local hasmarks=marks[startchar] + while current do + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + current=getnext(current) + else + local lg=ligature[char] + if lg then + if marks[char] then + hasmarks=true + end + stop=current + ligature=lg + current=getnext(current) + else + break + end + end + elseif char==false then + break + elseif id==disc_code then + discfound=current + break + else + break + end + end + if discfound then + local pre,post,replace=getdisc(discfound) + local match + if replace then + local char=ischar(replace,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and pre then + local char=ischar(pre,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and not pre or not replace then + local n=getnext(discfound) + local char=ischar(n,currentfont) + if char and ligature[char] then + match=true + end + end + if match then + local ishead=head==start + local prev=getprev(start) + if stop then + setnext(stop) + local copy=copy_node_list(start) + local tail=stop + local liat=find_node_tail(copy) + if pre then + setlink(liat,pre) + end + if replace then + setlink(tail,replace) + end + pre=copy + replace=start + else + setnext(start) + local copy=copy_node(start) + if pre then + setlink(copy,pre) + end + if replace then + setlink(start,replace) + end + pre=copy + replace=start + end + setdisc(discfound,pre,post,replace) + if prev then + setlink(prev,discfound) + else + setprev(discfound) + head=discfound + end + start=discfound + return head,start,true,true + end + end + local lig=ligature.ligature + if lig then + if stop then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) + else + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) + end + else + resetinjection(start) + setchar(start,lig) + if trace_ligatures then + logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) + end + end + return head,start,true,false + else + end + end + return head,start,false,false +end +function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) + if has_glyph_option(start,no_right_kern_code) then + return head,start,false + else + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true + end +end +function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) + if has_glyph_option(start,no_right_kern_code) then + return head,start,false + else + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + end + return head,start,true + else + break + end + end + else + break + end + end + return head,start,false + end + end +end +function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + elseif trace_bugs then + logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) + end + elseif trace_bugs then + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + else + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) + end + end + end + elseif trace_bugs then + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false +end +function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) + local startchar=getchar(start) + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true + end + end + end + break + end + end + end + return head,start,false +end +local chainprocs={} +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_subchain(...) +end +local logwarning=report_subchain +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_chain(...) +end +local logwarning=report_chain +local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash) + local char=getchar(start) + local replacement=replacements[char] + if replacement then + if trace_singles then + logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) + end + resetinjection(start) + setchar(start,replacement) + return head,start,true + else + return head,start,false + end +end +chainprocs.reversesub=reversesub +local function reportzerosteps(dataset,sequence) + logwarning("%s: no steps",cref(dataset,sequence)) +end +local function reportmoresteps(dataset,sequence) + logwarning("%s: more than 1 step",cref(dataset,sequence)) +end +local function getmapping(dataset,sequence,currentlookup) + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps==0 then + reportzerosteps(dataset,sequence) + currentlookup.mapping=false + return false + else + if nofsteps>1 then + reportmoresteps(dataset,sequence) + end + local mapping=steps[1].coverage + currentlookup.mapping=mapping + currentlookup.format=steps[1].format + return mapping + end +end +function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if trace_chains then + logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) + end + head,start=remove_node(head,start,true) + return head,getprev(start),true +end +function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local replacement=mapping[currentchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) + end + resetinjection(current) + setchar(current,replacement) + end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end + end + end + return head,start,false +end +function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local alternatives=mapping[currentchar] + if alternatives then + local choice,comment=get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) + end + end + end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end + end + end + return head,start,false +end +function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local replacement=mapping[startchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + end + return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) + end + end + return head,start,false +end +function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local ligatures=mapping[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) + end + else + local hasmarks=marks[startchar] + local current=getnext(start) + local discfound=false + local last=stop + local nofreplacements=1 + while current do + local id=getid(current) + if id==disc_code then + if not discfound then + discfound=current + end + if current==stop then + break + else + current=getnext(current) + end + else + local schar=getchar(current) + if skiphash and skiphash[schar] then + current=getnext(current) + else + local lg=ligatures[schar] + if lg then + ligatures=lg + last=current + nofreplacements=nofreplacements+1 + if marks[char] then + hasmarks=true + end + if current==stop then + break + else + current=getnext(current) + end + else + break + end + end + end + end + local ligature=ligatures.ligature + if ligature then + if chainindex then + stop=last + end + if trace_ligatures then + if start==stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + end + end + head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) + return head,start,true,nofreplacements,discfound + elseif trace_bugs then + if start==stop then + logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) + else + logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) + end + end + end + end + return head,start,false,0,false +end +function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true + end + end + end + return head,start,false +end +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then + break + end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end + local format=currentlookup.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + end + return head,start,true + else + break + end + end + end + end + end + end + end + return head,start,false +end +function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + end + end + end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true + end + end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) + end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) + end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + end + end + return head,start,false +end +function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local exitanchors=mapping[startchar] + if exitanchors then + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true + end + end + elseif trace_bugs then + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) + end + break + end + end + end + elseif trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) + end + end + return head,start,false +end +local function show_skip(dataset,sequence,char,ck,class) + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) +end +local userkern=nuts.pool and nuts.pool.newkern +do if not userkern then + local thekern=nuts.new("kern",1) + local setkern=nuts.setkern + userkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end end +local function checked(head) + local current=head + while current do + if getid(current)==glue_code then + local kern=userkern(getwidth(current)) + if head==current then + local next=getnext(current) + if next then + setlink(kern,next) + end + flush_node(current) + head=kern + current=next + else + local prev,next=getboth(current) + setlink(prev,kern,next) + flush_node(current) + current=next + end + else + current=getnext(current) + end + end + return head +end +local function setdiscchecked(d,pre,post,replace) + if pre then pre=checked(pre) end + if post then post=checked(post) end + if replace then replace=checked(replace) end + setdisc(d,pre,post,replace) +end +local noflags={ false,false,false,false } +local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) + local size=ck[5]-ck[4]+1 + local chainlookups=ck[6] + local done=false + if chainlookups then + if size==1 then + local chainlookup=chainlookups[1] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok + head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) + if ok then + done=true + end + else + logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) + end + end + else + local i=1 + local laststart=start + local nofchainlookups=#chainlookups + while start do + if skiphash then + while start do + local char=ischar(start,currentfont) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + break + end + else + break + end + end + end + local chainlookup=chainlookups[i] + if chainlookup then + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok,n + head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) + if ok then + done=true + if n and n>1 and i+n>nofchainlookups then + i=size + break + end + end + else + logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) + end + end + else + end + i=i+1 + if i>size or not start then + break + elseif start then + laststart=start + start=getnext(start) + end + end + if not start then + start=laststart + end + end + else + local replacements=ck[7] + if replacements then + head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) + else + done=true + if trace_contexts then + logprocess("%s: skipping match",cref(dataset,sequence)) + end + end + end + return head,start,done +end +local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) + if not start then + return head,start,false + end + local startishead=start==head + local seq=ck[3] + local f=ck[4] + local l=ck[5] + local s=#seq + local done=false + local sweepnode=sweepnode + local sweeptype=sweeptype + local sweepoverflow=false + local checkdisc=getprev(head) + local keepdisc=not sweepnode + local lookaheaddisc=nil + local backtrackdisc=nil + local current=start + local last=start + local prev=getprev(start) + local hasglue=false + local i=f + while i<=l do + local id=getid(current) + if id==glyph_code then + i=i+1 + last=current + current=getnext(current) + elseif id==glue_code then + i=i+1 + last=current + current=getnext(current) + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + lookaheaddisc=current + local replace=getreplace(current) + if not replace then + sweepoverflow=true + sweepnode=current + current=getnext(current) + else + while replace and i<=l do + if getid(replace)==glyph_code then + i=i+1 + end + replace=getnext(replace) + end + current=getnext(replace) + end + last=current + else + head,current=flattendisk(head,current) + end + else + last=current + current=getnext(current) + end + if current then + elseif sweepoverflow then + break + elseif sweeptype=="post" or sweeptype=="replace" then + current=getnext(sweepnode) + if current then + sweeptype=nil + sweepoverflow=true + else + break + end + else + break + end + end + if sweepoverflow then + local prev=current and getprev(current) + if not current or prev~=sweepnode then + local head=getnext(sweepnode) + local tail=nil + if prev then + tail=prev + setprev(current,sweepnode) + else + tail=find_node_tail(head) + end + setnext(sweepnode,current) + setprev(head) + setnext(tail) + appenddisc(sweepnode,head) + end + end + if l1 then + local current=prev + local i=f + local t=sweeptype=="pre" or sweeptype=="replace" + if not current and t and current==checkdisc then + current=getprev(sweepnode) + end + while current and i>1 do + local id=getid(current) + if id==glyph_code then + i=i-1 + elseif id==glue_code then + i=i-1 + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpost[current]~=notmatchreplace[current] then + backtrackdisc=current + end + local replace=getreplace(current) + while replace and i>1 do + if getid(replace)==glyph_code then + i=i-1 + end + replace=getnext(replace) + end + elseif notmatchpost[current]~=notmatchreplace[current] then + head,current=flattendisk(head,current) + end + end + current=getprev(current) + if t and current==checkdisc then + current=getprev(sweepnode) + end + end + end + local done=false + if lookaheaddisc then + local cf=start + local cl=getprev(lookaheaddisc) + local cprev=getprev(start) + local insertedmarks=0 + while cprev do + local char=ischar(cf,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cf=cprev + startishead=cf==head + cprev=getprev(cprev) + else + break + end + end + setlink(cprev,lookaheaddisc) + setprev(cf) + setnext(cl) + if startishead then + head=lookaheaddisc + end + local pre,post,replace=getdisc(lookaheaddisc) + local new=copy_node_list(cf) + local cnew=new + if pre then + setlink(find_node_tail(cf),pre) + end + if replace then + local tail=find_node_tail(new) + setlink(tail,replace) + end + for i=1,insertedmarks do + cnew=getnext(cnew) + end + cl=start + local clast=cnew + for i=f,l do + cl=getnext(cl) + clast=getnext(clast) + end + if not notmatchpre[lookaheaddisc] then + local ok=false + cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[lookaheaddisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) + end + start=getprev(lookaheaddisc) + sweephead[cf]=getnext(clast) or false + sweephead[new]=getnext(cl) or false + elseif backtrackdisc then + local cf=getnext(backtrackdisc) + local cl=start + local cnext=getnext(start) + local insertedmarks=0 + while cnext do + local char=ischar(cnext,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cl=cnext + cnext=getnext(cnext) + else + break + end + end + setlink(backtrackdisc,cnext) + setprev(cf) + setnext(cl) + local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) + local new=copy_node_list(cf) + local cnew=find_node_tail(new) + for i=1,insertedmarks do + cnew=getprev(cnew) + end + local clast=cnew + for i=f,l do + clast=getnext(clast) + end + if not notmatchpost[backtrackdisc] then + local ok=false + cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[backtrackdisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if post then + setlink(posttail,cf) + else + post=cf + end + if replace then + setlink(replacetail,new) + else + replace=new + end + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end + start=getprev(backtrackdisc) + sweephead[post]=getnext(clast) or false + sweephead[replace]=getnext(last) or false + else + local ok=false + head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + return head,start,done +end +local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) + local rule=ck[1] + local lookuptype=ck[8] or ck[2] + local nofseq=#ck[3] + local first=ck[4] + local last=ck[5] + local char=getchar(start) + logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", + cref(dataset,sequence),rule,match and "matches" or "nomatch", + gref(char),first-1,last-first+1,nofseq-last,lookuptype, + discseen and "" or "no ",sweepnode and "" or "not ") +end +local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) + local sweepnode=sweepnode + local sweeptype=sweeptype + local postreplace + local prereplace + local checkdisc + local discseen + if sweeptype then + if sweeptype=="replace" then + postreplace=true + prereplace=true + else + postreplace=sweeptype=="post" + prereplace=sweeptype=="pre" + end + checkdisc=getprev(head) + end + local currentfont=currentfont + local skipped + local startprev, + startnext=getboth(start) + local done + local nofcontexts=contexts.n + local startchar=nofcontext==1 or ischar(start,currentfont) + for k=1,nofcontexts do + local ck=contexts[k] + local seq=ck[3] + local f=ck[4] + if not startchar or not seq[f][startchar] then + goto next + end + local s=seq.n + local l=ck[5] + local current=start + local last=start + if s==1 then + goto next + end + if l>f then + local discfound + local n=f+1 + last=startnext + while n<=l do + if postreplace and not last then + last=getnext(sweepnode) + sweeptype=nil + end + if last then + local char,id=ischar(last,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + last=getnext(last) + elseif seq[n][char] then + if nl then + break + end + pre=getnext(pre) + else + notmatchpre[last]=true + break + end + end + if n<=l then + notmatchpre[last]=true + end + else + notmatchpre[last]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>l then + break + end + replace=getnext(replace) + else + notmatchreplace[last]=true + if notmatchpre[last] then + goto next + else + break + end + end + end + if notmatchpre[last] then + goto next + end + end + last=getnext(last) + else + goto next + end + else + goto next + end + end + end + if f>1 then + if startprev then + local prev=startprev + if prereplace and prev==checkdisc then + prev=getprev(sweepnode) + end + if prev then + local discfound + local n=f-1 + while n>=1 do + if prev then + local char,id=ischar(prev,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + prev=getprev(prev) + elseif seq[n][char] then + if n>1 then + prev=getprev(prev) + end + n=n-1 + elseif discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + else + break + end + else + goto next + end + elseif char==false then + if discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + end + else + goto next + end + break + elseif id==disc_code then + discseen=true + discfound=prev + notmatchpre[prev]=true + notmatchpost[prev]=nil + notmatchreplace[prev]=nil + local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) + if pre~=start and post~=start and replace~=start then + if post then + local n=n + while posttail do + if seq[n][getchar(posttail)] then + n=n-1 + if posttail==post or n<1 then + break + else + posttail=getprev(posttail) + end + else + notmatchpost[prev]=true + break + end + end + if n>=1 then + notmatchpost[prev]=true + end + else + notmatchpost[prev]=true + end + if replace then + while replacetail do + if seq[n][getchar(replacetail)] then + n=n-1 + if replacetail==replace or n<1 then + break + else + replacetail=getprev(replacetail) + end + else + notmatchreplace[prev]=true + if notmatchpost[prev] then + goto next + else + break + end + end + end + else + end + end + prev=getprev(prev) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[prev]) or sn[0xFFFC] then + n=n-1 + prev=getprev(prev) + else + goto next + end + elseif seq[n][0xFFFC] then + n=n-1 + prev=getprev(prev) + else + goto next + end + else + goto next + end + end + else + goto next + end + else + goto next + end + end + if s>l then + local current=last and getnext(last) + if not current and postreplace then + current=getnext(sweepnode) + end + if current then + local discfound + local n=l+1 + while n<=s do + if current then + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + current=getnext(current) + elseif seq[n][char] then + if ns then + break + else + pre=getnext(pre) + end + else + notmatchpre[current]=true + break + end + end + if n<=s then + notmatchpre[current]=true + end + else + notmatchpre[current]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>s then + break + else + replace=getnext(replace) + end + else + notmatchreplace[current]=true + if notmatchpre[current] then + goto next + else + break + end + end + end + else + end + current=getnext(current) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[current]) or sn[0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + elseif seq[n][0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next + end + else + goto next + end + end + else + goto next + end + end + if trace_contexts then + chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) + end + if discseen or sweepnode then + head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) + else + head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) + end + if done then + break + end + ::next:: + end + if discseen then + notmatchpre={} + notmatchpost={} + notmatchreplace={} + end + return head,start,done +end +handlers.gsub_context=handle_contextchain +handlers.gsub_contextchain=handle_contextchain +handlers.gsub_reversecontextchain=handle_contextchain +handlers.gpos_contextchain=handle_contextchain +handlers.gpos_context=handle_contextchain +local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps>1 then + reportmoresteps(dataset,sequence) + end + local l=steps[1].coverage[getchar(start)] + if l then + return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) + else + return head,start,false + end +end +chainprocs.gsub_context=chained_contextchain +chainprocs.gsub_contextchain=chained_contextchain +chainprocs.gsub_reversecontextchain=chained_contextchain +chainprocs.gpos_contextchain=chained_contextchain +chainprocs.gpos_context=chained_contextchain +local missing=setmetatableindex("table") +local logwarning=report_process +local resolved={} +local function logprocess(...) + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return + end + end + report_process(...) +end +local sequencelists=setmetatableindex(function(t,font) + local sequences=fontdata[font].resources.sequences + if not sequences or not next(sequences) then + sequences=false + end + t[font]=sequences + return sequences +end) +do + local autofeatures=fonts.analyzers.features + local featuretypes=otf.tables.featuretypes + local defaultscript=otf.features.checkeddefaultscript + local defaultlanguage=otf.features.checkeddefaultlanguage + local wildcard="*" + local default="dflt" + local function initialize(sequence,script,language,enabled,autoscript,autolanguage) + local features=sequence.features + if features then + local order=sequence.order + if order then + local featuretype=featuretypes[sequence.type or "unknown"] + for i=1,#order do + local kind=order[i] + local valid=enabled[kind] + if valid then + local scripts=features[kind] + local languages=scripts and ( + scripts[script] or + scripts[wildcard] or + (autoscript and defaultscript(featuretype,autoscript,scripts)) + ) + local enabled=languages and ( + languages[language] or + languages[wildcard] or + (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) + ) + if enabled then + return { valid,autofeatures[kind] or false,sequence,kind } + end + end + end + else + end + end + return false + end + function otf.dataset(tfmdata,font) + local shared=tfmdata.shared + local properties=tfmdata.properties + local language=properties.language or "dflt" + local script=properties.script or "dflt" + local enabled=shared.features + local autoscript=enabled and enabled.autoscript + local autolanguage=enabled and enabled.autolanguage + local res=resolved[font] + if not res then + res={} + resolved[font]=res + end + local rs=res[script] + if not rs then + rs={} + res[script]=rs + end + local rl=rs[language] + if not rl then + rl={ + } + rs[language]=rl + local sequences=tfmdata.resources.sequences + if sequences then + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1]=v + end + end + end + end + return rl + end +end +local function report_disc(what,n) + report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) +end +local function kernrun(disc,k_run,font,attr,...) + if trace_kernruns then + report_disc("kern",disc) + end + local prev,next=getboth(disc) + local nextstart=next + local done=false + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prevmarks=prev + while prevmarks do + local char=ischar(prevmarks,font) + if char and marks[char] then + prevmarks=getprev(prevmarks) + else + break + end + end + if prev and not ischar(prev,font) then + prev=false + end + if next and not ischar(next,font) then + next=false + end + if pre then + if k_run(pre,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,pre) + if k_run(prevmarks,"preinjections",pre,font,attr,...) then + done=true + end + setprev(pre) + setlink(prev,disc) + end + end + if post then + if k_run(post,"injections",nil,font,attr,...) then + done=true + end + if next then + setlink(posttail,next) + if k_run(posttail,"postinjections",next,font,attr,...) then + done=true + end + setnext(posttail) + setlink(disc,next) + end + end + if replace then + if k_run(replace,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,replace) + if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then + done=true + end + setprev(replace) + setlink(prev,disc) + end + if next then + setlink(replacetail,next) + if k_run(replacetail,"replaceinjections",next,font,attr,...) then + done=true + end + setnext(replacetail) + setlink(disc,next) + end + elseif prev and next then + setlink(prev,next) + if k_run(prevmarks,"emptyinjections",next,font,attr,...) then + done=true + end + setlink(prev,disc,next) + end + if done and trace_testruns then + report_disc("done",disc) + end + return nextstart,done +end +local function comprun(disc,c_run,...) + if trace_compruns then + report_disc("comp",disc) + end + local pre,post,replace=getdisc(disc) + local renewed=false + if pre then + sweepnode=disc + sweeptype="pre" + local new,done=c_run(pre,...) + if done then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,done=c_run(post,...) + if done then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,done=c_run(replace,...) + if done then + replace=new + renewed=true + end + end + sweepnode=nil + sweeptype=nil + if renewed then + if trace_testruns then + report_disc("done",disc) + end + setdisc(disc,pre,post,replace) + end + return getnext(disc),renewed +end +local function testrun(disc,t_run,c_run,...) + if trace_testruns then + report_disc("test",disc) + end + local prev,next=getboth(disc) + if not next then + return + end + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local renewed=false + if post or replace then + if post then + setlink(posttail,next) + else + post=next + end + if replace then + setlink(replacetail,next) + else + replace=next + end + local d_post=t_run(post,next,...) + local d_replace=t_run(replace,next,...) + if d_post>0 or d_replace>0 then + local d=d_replace>d_post and d_replace or d_post + local head=getnext(disc) + local tail=head + for i=2,d do + local nx=getnext(tail) + local id=getid(nx) + if id==disc_code then + head,tail=flattendisk(head,nx) + elseif id==glyph_code then + tail=nx + else + break + end + end + next=getnext(tail) + setnext(tail) + setprev(head) + local new=copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post=head + end + if replacetail then + setlink(replacetail,new) + else + replace=new + end + else + if posttail then + setnext(posttail) + else + post=nil + end + if replacetail then + setnext(replacetail) + else + replace=nil + end + end + setlink(disc,next) + end + if trace_testruns then + report_disc("more",disc) + end + if pre then + sweepnode=disc + sweeptype="pre" + local new,ok=c_run(pre,...) + if ok then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,ok=c_run(post,...) + if ok then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,ok=c_run(replace,...) + if ok then + replace=new + renewed=true + end + end + sweepnode=nil + sweeptype=nil + if renewed then + setdisc(disc,pre,post,replace) + if trace_testruns then + report_disc("done",disc) + end + end + return getnext(disc),renewed +end +local nesting=0 +local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + local start + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char,id=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done=true + end + end + if start then + start=getnext(start) + end + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) + end + end + return head,done +end +local function t_run_single(start,stop,font,attr,lookupcache) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + local startnext=getnext(start) + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + local l=nil + local d=0 + while s do + local char=ischar(s,font) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + lookupmatch=lg + else + break + end + else + break + end + end + if l and l.ligature then + lastd=d + end + else + end + else + end + if lastd then + return lastd + end + start=startnext + else + break + end + end + return 0 +end +local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getglyphdata(sub) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n,font) + if char then + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end + end + end + end + end +end +local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + local start + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done=true + break + elseif not start then + break + end + end + end + if start then + start=getnext(start) + end + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) + end + end + return head,done +end +local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getglyphdata(start) + end + local startnext=getnext(start) + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + local l=nil + local d=0 + while s do + local char=ischar(s) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getreplace(s) + if not s then + s=ss + ss=nil + end + end + lookupmatch=lg + else + break + end + else + break + end + end + if l and l.ligature then + lastd=d + end + end + end + else + end + if lastd then + return lastd + end + start=startnext + else + break + end + end + return 0 +end +local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getglyphdata(sub) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n) + if char then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end + end + end + end + end + end +end +local txtdirstate,pardirstate do + local getdirection=nuts.getdirection + txtdirstate=function(start,stack,top,rlparmode) + local dir,pop=getdirection(start) + if pop then + if top==1 then + return 0,rlparmode + else + top=top-1 + if stack[top]==righttoleft_code then + return top,-1 + else + return top,1 + end + end + elseif dir==lefttoright_code then + top=top+1 + stack[top]=lefttoright_code + return top,1 + elseif dir==righttoleft_code then + top=top+1 + stack[top]=righttoleft_code + return top,-1 + else + return top,rlparmode + end + end + pardirstate=function(start) + local dir=getdirection(start) + if dir==lefttoright_code then + return 1,1 + elseif dir==righttoleft_code then + return -1,-1 + else + return 0,0 + end + end +end +otf.helpers=otf.helpers or {} +otf.helpers.txtdirstate=txtdirstate +otf.helpers.pardirstate=pardirstate +do + local fastdisc=true + local testdics=false + directives.register("otf.fastdisc",function(v) fastdisc=v end) + local otfdataset=nil + local getfastdisc={ __index=function(t,k) + local v=usesfont(k,currentfont) + t[k]=v + return v + end } + local getfastspace={ __index=function(t,k) + local v=isspace(k,threshold) or false + t[k]=v + return v + end } + function otf.featuresprocessor(head,font,attr,direction,n) + local sequences=sequencelists[font] + nesting=nesting+1 + if nesting==1 then + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if not otfdataset then + otfdataset=otf.dataset + end + discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) + spaces=setmetatable({},getfastspace) + elseif currentfont~=font then + report_warning("nested call with a different font, level %s, quitting",nesting) + nesting=nesting-1 + return head,false + end + if trace_steps then + checkstep(head) + end + local initialrl=0 + if getid(head)==par_code and start_of_par(head) then + initialrl=pardirstate(head) + elseif direction==righttoleft_code then + initialrl=-1 + end + local datasets=otfdataset(tfmdata,font,attr) + local dirstack={ nil } + sweephead={} + for s=1,#datasets do + local dataset=datasets[s] + local attribute=dataset[2] + local sequence=dataset[3] + local rlparmode=initialrl + local topstack=0 + local typ=sequence.type + local gpossing=typ=="gpos_single" or typ=="gpos_pair" + local forcetestrun=typ=="gsub_ligature" + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local skiphash=sequence.skiphash + if not steps then + local h,ok=handler(head,dataset,sequence,initialrl,font,attr) + if h and h~=head then + head=h + end + elseif typ=="gsub_reversecontextchain" then + local start=find_node_tail(head) + local rlmode=0 + local merged=steps.merged + while start do + local char=ischar(start,font) + if char then + local m=merged[char] + if m then + local a + if attr then + a=getglyphdata(start) + end + if not a or (a==attr) then + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + break + end + end + end + if start then + start=getprev(start) + end + else + start=getprev(start) + end + else + start=getprev(start) + end + else + start=getprev(start) + end + end + else + local start=head + local rlmode=initialrl + if nofsteps==1 then + local step=steps[1] + local lookupcache=step.coverage + while start do + local char,id=ischar(start,font) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + local lookupmatch=lookupcache[char] + if lookupmatch then + local a + if attr then + if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then + a=true + end + elseif not attribute or getstate(start,attribute) then + a=true + end + if a then + local ok,df + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + elseif start then + start=getnext(start) + end + else + start=getnext(start) + end + else + start=getnext(start) + end + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + else + start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + end + else + start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + else + local merged=steps.merged + while start do + local char,id=ischar(start,font) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + local m=merged[char] + if m then + local a + if attr then + if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then + a=true + end + elseif not attribute or getstate(start,attribute) then + a=true + end + if a then + local ok,df + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + break + elseif ok then + break + elseif not start then + break + end + end + end + if df then + elseif start then + start=getnext(start) + end + else + start=getnext(start) + end + else + start=getnext(start) + end + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + else + start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + end + else + start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + end + end + if trace_steps then + registerstep(head) + end + end + nesting=nesting-1 + return head + end + function otf.datasetpositionprocessor(head,font,direction,dataset) + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if type(dataset)=="number" then + dataset=otfdataset(tfmdata,font,0)[dataset] + end + local sequence=dataset[3] + local typ=sequence.type + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local done=false + local dirstack={ nil } + local start=head + local initialrl=(direction==righttoleft_code) and -1 or 0 + local rlmode=initialrl + local rlparmode=initialrl + local topstack=0 + local merged=steps.merged + local position=0 + while start do + local char,id=ischar(start,font) + if char then + position=position+1 + local m=merged[char] + if m then + if skiphash and skiphash[char] then + start=getnext(start) + else + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + break + elseif not start then + break + end + end + end + if start then + start=getnext(start) + end + end + else + start=getnext(start) + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end + end + return head + end +end +local plugins={} +otf.plugins=plugins +local report=logs.reporter("fonts") +function otf.registerplugin(name,f) + if type(name)=="string" and type(f)=="function" then + plugins[name]={ name,f } + report() + report("plugin %a has been loaded, please be aware of possible side effects",name) + report() + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end + end +end +function otf.plugininitializer(tfmdata,value) + if type(value)=="string" then + tfmdata.shared.plugin=plugins[value] + end +end +function otf.pluginprocessor(head,font,attr,direction) + local s=fontdata[font].shared + local p=s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font,attr,direction) + else + return head,false + end +end +function otf.featuresinitializer(tfmdata,value) +end +registerotffeature { + name="features", + description="features", + default=true, + initializers={ + position=1, + node=otf.featuresinitializer, + plug=otf.plugininitializer, + }, + processors={ + node=otf.featuresprocessor, + plug=otf.pluginprocessor, + } +} +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} +otf.handlers=handlers +if context then + return +else +end +local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end +local tag="kern" + function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) + local shared=fontdata[font].shared + local features=shared and shared.features + local enabled=features and features.spacekern and features[tag] + if enabled then + setspacekerns(font,sequence) + end + return head,enabled + end +local function hasspacekerns(data) + local resources=data.resources + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps and sequence.features[tag] then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + return true + end + for k,v in next,coverage do + if v[32] then + return true + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + return true + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + return true + end + end + end + end + end + end + end + end + end + end + return false +end +otf.readers.registerextender { + name="spacekerns", + action=function(data) + data.properties.hasspacekerns=hasspacekerns(data) + end +} +local function spaceinitializer(tfmdata,value) + local resources=tfmdata.resources + local spacekerns=resources and resources.spacekerns + if value and spacekerns==nil then + local rawdata=tfmdata.shared and tfmdata.shared.rawdata + local properties=rawdata.properties + if properties and properties.hasspacekerns then + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + local left={} + local right={} + local last=0 + local feat=nil + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local kern=sequence.features[tag] + if kern then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + if feat then + for script,languages in next,kern do + local f=feat[script] + if f then + for l in next,languages do + f[l]=true + end + else + feat[script]=languages + end + end + else + feat=kern + end + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + right[k]=v + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + left[k]=kern + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + right[k]=one[3] + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + left[k]=one[3] + end + end + end + end + end + end + last=i + end + else + end + end + end + left=next(left) and left or false + right=next(right) and right or false + if left or right then + spacekerns={ + left=left, + right=right, + } + if last>0 then + local triggersequence={ + features={ [tag]=feat or { dflt={ dflt=true,} } }, + flags=noflags, + name="trigger_space_kerns", + order={ tag }, + type="trigger_space_kerns", + left=left, + right=right, + } + insert(sequences,last,triggersequence) + end + end + end + end + resources.spacekerns=spacekerns + end + return spacekerns +end +registerotffeature { + name="spacekern", + description="space kern injection", + default=true, + initializers={ + node=spaceinitializer, + }, +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd” 73c9531c79df5ada320cb20777f7ed49] --- + +if not modules then modules={} end modules ['font-osd']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", + copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local insert,imerge,copy,tohash=table.insert,table.imerge,table.copy,table.tohash +local next,type=next,type +local report=logs.reporter("otf","devanagari") +fonts=fonts or {} +fonts.analyzers=fonts.analyzers or {} +fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } +local otf=fonts.handlers.otf +local handlers=otf.handlers +local methods=fonts.analyzers.methods +local otffeatures=fonts.constructors.features.otf +local registerotffeature=otffeatures.register +local nuts=nodes.nuts +local getnext=nuts.getnext +local getprev=nuts.getprev +local getboth=nuts.getboth +local getid=nuts.getid +local getchar=nuts.getchar +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local setlink=nuts.setlink +local setnext=nuts.setnext +local setprev=nuts.setprev +local setchar=nuts.setchar +local getprop=nuts.getprop +local setprop=nuts.setprop +local getstate=nuts.getstate +local setstate=nuts.setstate +local ischar=nuts.ischar +local insert_node_after=nuts.insert_after +local copy_node=nuts.copy +local remove_node=nuts.remove +local flush_list=nuts.flush_list +local flush_node=nuts.flush_node +local copyinjection=nodes.injections.copy +local unsetvalue=attributes.unsetvalue +local fontdata=fonts.hashes.identifiers +local a_syllabe=attributes.private('syllabe') +local dotted_circle=0x25CC +local c_nbsp=0x00A0 +local c_zwnj=0x200C +local c_zwj=0x200D +local states=fonts.analyzers.states +local s_rphf=states.rphf +local s_half=states.half +local s_pref=states.pref +local s_blwf=states.blwf +local s_pstf=states.pstf +local s_init=states.init +local replace_all_nbsp=nil +replace_all_nbsp=function(head) + replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) + return head + end + return replace_all_nbsp(head) +end +local processcharacters=nil +if context then + local fontprocesses=fonts.hashes.processes + function processcharacters(head,font) + local processors=fontprocesses[font] + for i=1,#processors do + head=processors[i](head,font,0) + end + return head + end +else + function processcharacters(head,font) + local processors=fontdata[font].shared.processes + for i=1,#processors do + head=processors[i](head,font,0) + end + return head + end +end +local indicgroups=characters and characters.indicgroups +if not indicgroups and characters then + local indic={ + c={}, + i={}, + d={}, + m={}, + s={}, + o={}, + } + local indicmarks={ + l={}, + t={}, + b={}, + r={}, + s={}, + } + local indicclasses={ + nukta={}, + halant={}, + ra={}, + anudatta={}, + } + local indicorders={ + bp={}, + ap={}, + bs={}, + as={}, + bh={}, + ah={}, + bm={}, + am={}, + } + for k,v in next,characters.data do + local i=v.indic + if i then + indic[i][k]=true + i=v.indicmark + if i then + if i=="s" then + local s=v.specials + indicmarks[i][k]={ s[2],s[3] } + else + indicmarks[i][k]=true + end + end + i=v.indicclass + if i then + indicclasses[i][k]=true + end + i=v.indicorder + if i then + indicorders[i][k]=true + end + end + end + indicgroups={ + consonant=indic.c, + independent_vowel=indic.i, + dependent_vowel=indic.d, + vowel_modifier=indic.m, + stress_tone_mark=indic.s, + pre_mark=indicmarks.l, + above_mark=indicmarks.t, + below_mark=indicmarks.b, + post_mark=indicmarks.r, + twopart_mark=indicmarks.s, + nukta=indicclasses.nukta, + halant=indicclasses.halant, + ra=indicclasses.ra, + anudatta=indicclasses.anudatta, + before_postscript=indicorders.bp, + after_postscript=indicorders.ap, + before_half=indicorders.bh, + after_half=indicorders.ah, + before_subscript=indicorders.bs, + after_subscript=indicorders.as, + before_main=indicorders.bm, + after_main=indicorders.am, + } + indic=nil + indicmarks=nil + indicclasses=nil + indicorders=nil + characters.indicgroups=indicgroups +end +local consonant=indicgroups.consonant +local independent_vowel=indicgroups.independent_vowel +local dependent_vowel=indicgroups.dependent_vowel +local vowel_modifier=indicgroups.vowel_modifier +local stress_tone_mark=indicgroups.stress_tone_mark +local pre_mark=indicgroups.pre_mark +local above_mark=indicgroups.above_mark +local below_mark=indicgroups.below_mark +local post_mark=indicgroups.post_mark +local twopart_mark=indicgroups.twopart_mark +local nukta=indicgroups.nukta +local halant=indicgroups.halant +local ra=indicgroups.ra +local anudatta=indicgroups.anudatta +local before_postscript=indicgroups.before_postscript +local after_postscript=indicgroups.after_postscript +local before_half=indicgroups.before_half +local after_half=indicgroups.after_half +local before_subscript=indicgroups.before_subscript +local after_subscript=indicgroups.after_subscript +local before_main=indicgroups.before_main +local after_main=indicgroups.after_main +local mark_four=table.merged ( + pre_mark, + above_mark, + below_mark, + post_mark +) +local mark_above_below_post=table.merged ( + above_mark, + below_mark, + post_mark +) +local zw_char={ + [c_zwnj]=true, + [c_zwj ]=true, +} +local dflt_true={ + dflt=true, +} +local two_defaults={} +local one_defaults={} +local false_flags={ false,false,false,false } +local sequence_reorder_matras={ + features={ dv01=two_defaults }, + flags=false_flags, + name="dv01_reorder_matras", + order={ "dv01" }, + type="devanagari_reorder_matras", + nofsteps=1, + steps={ + { + coverage=pre_mark, + } + } +} +local sequence_reorder_reph={ + features={ dv02=two_defaults }, + flags=false_flags, + name="dv02_reorder_reph", + order={ "dv02" }, + type="devanagari_reorder_reph", + nofsteps=1, + steps={ + { + coverage={}, + } + } +} +local sequence_reorder_pre_base_reordering_consonants={ + features={ dv03=one_defaults }, + flags=false_flags, + name="dv03_reorder_pre_base_reordering_consonants", + order={ "dv03" }, + type="devanagari_reorder_pre_base_reordering_consonants", + nofsteps=1, + steps={ + { + coverage={}, + } + } +} +local sequence_remove_joiners={ + features={ dv04=one_defaults }, + flags=false_flags, + name="dv04_remove_joiners", + order={ "dv04" }, + type="devanagari_remove_joiners", + nofsteps=1, + steps={ + { + coverage=zw_char, + }, + } +} +local basic_shaping_forms={ + akhn=true, + blwf=true, + cjct=true, + half=true, + nukt=true, + pref=true, + pstf=true, + rkrf=true, + rphf=true, + vatu=true, + locl=true, +} +local valid={ + abvs=true, + akhn=true, + blwf=true, + calt=true, + cjct=true, + half=true, + haln=true, + nukt=true, + pref=true, + pres=true, + pstf=true, + psts=true, + rkrf=true, + rphf=true, + vatu=true, + pres=true, + abvs=true, + blws=true, + psts=true, + haln=true, + calt=true, + locl=true, +} +local scripts={} +local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" } +local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" } +local nofscripts=#scripts_one +for i=1,nofscripts do + local one=scripts_one[i] + local two=scripts_two[i] + scripts[one]=true + scripts[two]=true + two_defaults[two]=dflt_true + one_defaults[one]=dflt_true + one_defaults[two]=dflt_true +end +local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end +local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end +local function initializedevanagi(tfmdata) + local script,language=otf.scriptandlanguage(tfmdata,attr) + if scripts[script] then + local resources=tfmdata.resources + local devanagari=resources.devanagari + if not devanagari then + report("adding devanagari features to font") + local gsubfeatures=resources.features.gsub + local sequences=resources.sequences + local sharedfeatures=tfmdata.shared.features + gsubfeatures["dv01"]=two_defaults + gsubfeatures["dv02"]=two_defaults + gsubfeatures["dv03"]=one_defaults + gsubfeatures["dv04"]=one_defaults + local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) + local reorder_reph=copy(sequence_reorder_reph) + local reorder_matras=copy(sequence_reorder_matras) + local remove_joiners=copy(sequence_remove_joiners) + local lastmatch=0 + for s=1,#sequences do + local features=sequences[s].features + if features then + for k,v in next,features do + if k=="locl" then + local steps=sequences[s].steps + local nofsteps=sequences[s].nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,pre_mark do + local locl=coverage[k] + if locl then + if #locl>0 then + for j=1,#locl do + local ck=locl[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + locl=coverage[k] + end + end + end + end + end + end + if locl then + reorder_matras.steps[1].coverage[locl]=true + end + end + end + end + end + end + if basic_shaping_forms[k] then + lastmatch=lastmatch+1 + if s~=lastmatch then + table.insert(sequences,lastmatch,table.remove(sequences,s)) + end + end + end + end + end + local insertindex=lastmatch+1 + if tfmdata.properties.language then + dflt_true[tfmdata.properties.language]=true + end + insert(sequences,insertindex,reorder_pre_base_reordering_consonants) + insert(sequences,insertindex,reorder_reph) + insert(sequences,insertindex,reorder_matras) + insert(sequences,insertindex,remove_joiners) + local blwfcache={} + local vatucache={} + local pstfcache={} + local seqsubset={} + local rephstep={ + coverage={} + } + local devanagari={ + reph=false, + vattu=false, + blwfcache=blwfcache, + vatucache=vatucache, + pstfcache=pstfcache, + seqsubset=seqsubset, + reorderreph=rephstep, + } + reorder_reph.steps={ rephstep } + local pre_base_reordering_consonants={} + reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants + resources.devanagari=devanagari + for s=1,#sequences do + local sequence=sequences[s] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local features=sequence.features + local has_rphf=features.rphf + local has_blwf=features.blwf + local has_vatu=features.vatu + local has_pstf=features.pstf + if has_rphf and has_rphf[script] then + devanagari.reph=true + elseif (has_blwf and has_blwf[script] ) or (has_vatu and has_vatu[script] ) then + devanagari.vattu=true + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,coverage do + for h,w in next,halant do + if v[h] then + if not blwfcache[k] then + blwfcache[k]=v + end + end + if has_vatu and has_vatu[script] and not vatucache[k] then + vatucache[k]=v + end + end + end + end + end + elseif has_pstf and has_pstf[script] then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,coverage do + if not pstfcache[k] then + pstfcache[k]=v + end + end + for k,v in next,ra do + local r=coverage[k] + if r then + local found=false + if #r>0 then + for j=1,#r do + local ck=r[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups and chainlookups[f] then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local h=coverage[k] + if h then + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + if found then + break + end + end + end + end + end + end + end + else + for k,v in next,r do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + end + if found then + break + end + end + end + end + end + end + for kind,spec in next,features do + if valid[kind] and valid_two(spec)then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local reph,rephbase=false,false + if kind=="rphf" then + for k,v in next,ra do + local r=coverage[k] + if r then + rephbase=k + local h=false + if #r>0 then + for j=1,#r do + local ck=r[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local r=coverage[k] + if r then + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + if h then + break + end + end + end + end + end + end + end + else + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + end + if reph then + break + end + end + end + end + seqsubset[#seqsubset+1]={ kind,coverage,reph,rephbase } + end + end + end + if kind=="pref" then + local steps=sequence.steps + local nofsteps=sequence.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,halant do + local h=coverage[k] + if h then + local found=false + if #h>0 then + for j=1,#h do + local ck=h[j] + local f=ck[4] + local chainlookups=ck[6] + if chainlookups then + local chainlookup=chainlookups[f] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local steps=chainstep.steps + local nofsteps=chainstep.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local h=coverage[k] + if h then + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + if found then + break + end + end + end + end + end + end + end + else + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[found]=true + break + end + end + end + if found then + break + end + end + end + end + end + end + end + end + if two_defaults[script] then + sharedfeatures["dv01"]=true + sharedfeatures["dv02"]=true + sharedfeatures["dv03"]=true + sharedfeatures["dv04"]=true + elseif one_defaults[script] then + sharedfeatures["dv03"]=true + sharedfeatures["dv04"]=true + end + if script=="mlym" or script=="taml" then + devanagari.left_matra_before_base=true + end + end + end +end +registerotffeature { + name="devanagari", + description="inject additional features", + default=true, + initializers={ + node=initializedevanagi, + }, +} +local show_syntax_errors=false +local function inject_syntax_error(head,current,char) + local signal=copy_node(current) + copyinjection(signal,current) + if pre_mark[char] then + setchar(signal,dotted_circle) + else + setchar(current,dotted_circle) + end + return insert_node_after(head,current,signal) +end +local function initialize_one(font,attr) + local tfmdata=fontdata[font] + local datasets=otf.dataset(tfmdata,font,attr) + local devanagaridata=datasets.devanagari + if not devanagaridata then + devanagaridata={ + reph=false, + vattu=false, + blwfcache={}, + vatucache={}, + pstfcache={}, + } + datasets.devanagari=devanagaridata + local resources=tfmdata.resources + local devanagari=resources.devanagari + for s=1,#datasets do + local dataset=datasets[s] + if dataset and dataset[1] then + local kind=dataset[4] + if kind=="rphf" then + devanagaridata.reph=true + elseif kind=="blwf" or kind=="vatu" then + devanagaridata.vattu=true + devanagaridata.blwfcache=devanagari.blwfcache + devanagaridata.vatucache=devanagari.vatucache + devanagaridata.pstfcache=devanagari.pstfcache + end + end + end + end + return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache,devanagaridata.vatucache,devanagaridata.pstfcache +end +local function contextchain(contexts,n) + local char=getchar(n) + for k=1,#contexts do + local ck=contexts[k] + local seq=ck[3] + local f=ck[4] + local l=ck[5] + if (l-f)==1 and seq[f+1][char] then + local ok=true + local c=n + for i=l+1,#seq do + c=getnext(c) + if not c or not seq[i][ischar(c)] then + ok=false + break + end + end + if ok then + c=getprev(n) + for i=1,f-1 do + c=getprev(c) + if not c or not seq[f-i][ischar(c)] then + ok=false + end + end + end + if ok then + return true + end + end + end + return false +end +local function order_matras(c) + local cn=getnext(c) + local char=getchar(cn) + while dependent_vowel[char] do + local next=getnext(cn) + local cc=c + local cchar=getchar(cc) + while cc~=cn do + if (above_mark[char] and (below_mark[cchar] or post_mark[cchar])) or (below_mark[char] and (post_mark[cchar])) then + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + setnext(getprev(cc),cn) + setprev(cn,getprev(cc)) + setnext(cn,cc) + setprev(cc,cn) + break + end + cc=getnext(cc) + cchar=getchar(cc) + end + cn=next + char=getchar(cn) + end +end +local function reorder_one(head,start,stop,font,attr,nbspaces) + local reph,vattu,blwfcache,vatucache,pstfcache=initialize_one(font,attr) + local devanagari=fontdata[font].resources.devanagari + local current=start + local n=getnext(start) + local base=nil + local firstcons=nil + local lastcons=nil + local basefound=false + if reph and ra[getchar(start)] and halant[getchar(n)] then + if n==stop then + return head,stop,nbspaces + end + if getchar(getnext(n))==c_zwj then + current=start + else + current=getnext(n) + setstate(start,s_rphf) + end + end + if getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + firstcons=current + lastcons=current + current=getnext(current) + if current~=stop then + local char=getchar(current) + if nukta[char] then + current=getnext(current) + char=getchar(current) + end + if char==c_zwj and current~=stop then + local next=getnext(current) + if next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=next and getnext(next) or nil + local changestop=next==stop + local tempcurrent=copy_node(next) + copyinjection(tempcurrent,next) + local nextcurrent=copy_node(current) + copyinjection(nextcurrent,current) + setlink(tempcurrent,nextcurrent) + setstate(tempcurrent,s_blwf) + tempcurrent=processcharacters(tempcurrent,font) + setstate(tempcurrent,unsetvalue) + if getchar(next)==getchar(tempcurrent) then + flush_list(tempcurrent) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end + else + setchar(current,getchar(tempcurrent)) + local freenode=getnext(current) + setlink(current,tmp) + flush_node(freenode) + flush_list(tempcurrent) + if changestop then + stop=current + end + end + end + end + end + end + end + while not basefound do + local char=getchar(current) + if consonant[char] then + setstate(current,s_half) + if not firstcons then + firstcons=current + end + lastcons=current + if not base then + base=current + elseif blwfcache[char] then + setstate(current,s_blwf) + elseif pstfcache[char] then + setstate(current,s_pstf) + else + base=current + end + end + basefound=current==stop + current=getnext(current) + end + if base~=lastcons then + local np=base + local n=getnext(base) + local ch=getchar(n) + if nukta[ch] then + np=n + n=getnext(n) + ch=getchar(n) + end + if halant[ch] then + if lastcons~=stop then + local ln=getnext(lastcons) + if nukta[getchar(ln)] then + lastcons=ln + end + end + local nn=getnext(n) + local ln=getnext(lastcons) + setlink(np,nn) + setnext(lastcons,n) + if ln then + setprev(ln,n) + end + setnext(n,ln) + setprev(n,lastcons) + if lastcons==stop then + stop=n + end + end + end + n=getnext(start) + if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then + local matra=base + if base~=stop then + local next=getnext(base) + if dependent_vowel[getchar(next)] then + matra=next + end + end + local sp=getprev(start) + local nn=getnext(n) + local mn=getnext(matra) + setlink(sp,nn) + setlink(matra,start) + setlink(n,mn) + if head==start then + head=nn + end + start=nn + if matra==stop then + stop=n + end + end + local current=start + while current~=stop do + local next=getnext(current) + if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then + setstate(current,unsetvalue) + end + current=next + end + if base~=stop and getstate(base) then + local next=getnext(base) + if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then + setstate(base,unsetvalue) + end + end + local current,allreordered,moved=start,false,{ [base]=true } + local a,b,p,bn=base,base,base,getnext(base) + if base~=stop and nukta[getchar(bn)] then + a,b,p=bn,bn,bn + end + while not allreordered do + local c=current + local n=getnext(current) + local l=nil + if c~=stop then + local ch=getchar(n) + if nukta[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if halant[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + local tpm=twopart_mark[ch] + while tpm do + local extra=copy_node(n) + copyinjection(extra,n) + ch=tpm[1] + setchar(n,ch) + setchar(extra,tpm[2]) + head=insert_node_after(head,current,extra) + tpm=twopart_mark[ch] + end + while c~=stop and dependent_vowel[ch] do + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if vowel_modifier[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop and stress_tone_mark[ch] then + c=n + n=getnext(n) + end + end + end + end + local bp=getprev(firstcons) + local cn=getnext(current) + local last=getnext(c) + while cn~=last do + if pre_mark[getchar(cn)] then + if devanagari.left_matra_before_base then + local prev,next=getboth(cn) + setlink(prev,next) + if cn==stop then + stop=getprev(cn) + end + if base==start then + if head==start then + head=cn + end + start=cn + end + setlink(getprev(base),cn) + setlink(cn,base) + cn=next + else + if bp then + setnext(bp,cn) + end + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + if cn==stop then + stop=prev + end + setprev(cn,bp) + setlink(cn,firstcons) + if firstcons==start then + if head==start then + head=cn + end + start=cn + end + cn=next + end + elseif current~=base and dependent_vowel[getchar(cn)] then + local prev,next=getboth(cn) + if next then + setprev(next,prev) + end + setnext(prev,next) + if cn==stop then + stop=prev + end + setlink(b,cn,getnext(b)) + order_matras(cn) + cn=next + elseif current==base and dependent_vowel[getchar(cn)] then + local cnn=getnext(cn) + order_matras(cn) + cn=cnn + while cn~=last and dependent_vowel[getchar(cn)] do + cn=getnext(cn) + end + else + cn=getnext(cn) + end + end + allreordered=c==stop + current=getnext(c) + end + if reph or vattu then + local current,cns=start,nil + while current~=stop do + local c=current + local n=getnext(current) + if ra[getchar(current)] and halant[getchar(n)] then + c=n + n=getnext(n) + local b,bn=base,base + while bn~=stop do + local next=getnext(bn) + if dependent_vowel[getchar(next)] then + b=next + end + bn=next + end + if getstate(current,s_rphf) then + if b~=current then + if current==start then + if head==start then + head=n + end + start=n + end + if b==stop then + stop=c + end + local prev=getprev(current) + setlink(prev,n) + local next=getnext(b) + setlink(c,next) + setlink(b,current) + end + elseif cns and getnext(cns)~=current then + local cp=getprev(current) + local cnsn=getnext(cns) + setlink(cp,n) + setlink(cns,current) + setlink(c,cnsn) + if c==stop then + stop=cp + break + end + current=getprev(n) + end + else + local char=getchar(current) + if consonant[char] then + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end + if not vatucache[char] then + next=getnext(cns) + while dependent_vowel[getchar(next)] do + cns=next + next=getnext(cns) + end + end + elseif char==c_nbsp then + nbspaces=nbspaces+1 + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end + if not vatucache[char] then + next=getnext(cns) + while dependent_vowel[getchar(next)] do + cns=next + next=getnext(cns) + end + end + end + end + current=getnext(current) + end + end + if getchar(base)==c_nbsp then + nbspaces=nbspaces-1 + if base==stop then + stop=getprev(stop) + end + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces +end +function handlers.devanagari_reorder_matras(head,start) + local current=start + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + local next=getnext(current) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + if next then + local char=ischar(next,startfont) + if char and zw_char[char] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + local startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + break + end + else + break + end + current=next + end + return head,start,true +end +local rephbase={} +function handlers.devanagari_reorder_reph(head,start) + local current=getnext(start) + local startnext=nil + local startprev=nil + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + ::step_1:: + local char=ischar(start,startfont) + local rephbase=rephbase[startfont][char] + if char and after_subscript[rephbase] then + goto step_5 + end + ::step_2:: + if char and not after_postscript[rephbase] then + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + local next=getnext(current) + if next then + local nextchar=ischar(next,startfont) + if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + startattr=getprop(start,a_syllabe) + break + end + current=getnext(current) + else + break + end + end + end + ::step_3:: + if not startnext then + if char and after_main[rephbase] then + current=getnext(start) + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if consonant[char] and not getstate(current,s_pref) then + startnext=getnext(start) + head=remove_node(head,start) + setlink(current,start) + setlink(start,getnext(current)) + start=startnext + startattr=getprop(start,a_syllabe) + break + end + current=getnext(current) + else + break + end + end + end + end + ::step_4:: + if not startnext then + if char and before_postscript[rephbase] then + current=getnext(start) + local c=nil + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if getstate(current,s_pstf) then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(current),start) + setlink(start,current) + start=startnext + startattr=getprop(start,a_syllabe) + break + elseif not c and (vowel_modifier[char] or stress_tone_mark[char] ) then + c=current + end + current=getnext(current) + else + if c then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(c),start) + setlink(start,c) + start=startnext + startattr=getprop(start,a_syllabe) + end + break + end + end + end + end + ::step_5:: + if not startnext then + current=getnext(start) + local c=nil + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + local state=getstate(current) + if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then + c=current + elseif after_subscript[rephbase] and (state==s_pstf) then + c=current + end + current=getnext(current) + else + break + end + end + if c then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(c),start) + setlink(start,c) + start=startnext + startattr=getprop(start,a_syllabe) + end + end + ::step_6:: + if not startnext then + current=start + local next=getnext(current) + while next do + local nextchar=ischar(next,startfont) + if nextchar and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + else + break + end + end + if start~=current then + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,getnext(current)) + setlink(current,start) + start=startnext + end + end + return head,start,true +end +local reordered_pre_base_reordering_consonants={} +function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) + if reordered_pre_base_reordering_consonants[start] then + return head,start,true + end + local current=start + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + local next=getnext(current) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] then + if next then + local char=ischar(next,startfont) + if char and zw_char[char] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end + end + local startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + reordered_pre_base_reordering_consonants[start]=true + start=startnext + return head,start,true + end + else + break + end + current=next + end + local startattr=getprop(start,a_syllabe) + local current=getprev(start) + while current and getprop(current,a_syllabe)==startattr do + local char=ischar(current) + if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then + startnext=getnext(start) + head=remove_node(head,start) + if current==head then + setlink(start,current) + head=start + else + setlink(getprev(current),start) + setlink(start,current) + end + reordered_pre_base_reordering_consonants[start]=true + start=startnext + break + end + current=getprev(current) + end + return head,start,true +end +function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement) + local stop=getnext(start) + local font=getfont(start) + local last=start + while stop do + local char=ischar(stop,font) + if char and (char==c_zwnj or char==c_zwj) then + last=stop + stop=getnext(stop) + else + break + end + end + local prev=getprev(start) + if stop then + setnext(last) + setlink(prev,stop) + elseif prev then + setnext(prev) + end + if head==start then + head=stop + end + flush_list(start) + return head,stop,true +end +local function initialize_two(font,attr) + local devanagari=fontdata[font].resources.devanagari + if devanagari then + return devanagari.seqsubset or {},devanagari.reorderreph or {} + else + return {},{} + end +end +local function reorder_two(head,start,stop,font,attr,nbspaces) + local seqsubset,reorderreph=initialize_two(font,attr) + local halfpos=nil + local basepos=nil + local subpos=nil + local postpos=nil + reorderreph.coverage={} + rephbase[font]={} + for i=1,#seqsubset do + local subset=seqsubset[i] + local kind=subset[1] + local lookupcache=subset[2] + if kind=="rphf" then + reorderreph.coverage[subset[3]]=true + rephbase[font][subset[3]]=subset[4] + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + local afternext=next~=stop and getnext(next) + if afternext and zw_char[getchar(afternext)] then + current=afternext + elseif current==start then + setstate(current,s_rphf) + current=next + else + current=next + end + end + end + end + current=getnext(current) + end + elseif kind=="pref" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_pref) + setstate(next,s_pref) + current=next + end + end + end + end + current=getnext(current) + end + elseif kind=="half" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if next~=stop and getchar(getnext(next))==c_zwnj then + current=next + elseif (not getstate(current)) then + setstate(current,s_half) + if not halfpos then + halfpos=current + end + end + current=getnext(current) + end + end + end + current=getnext(current) + end + elseif kind=="blwf" or kind=="vatu" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_blwf) + setstate(next,s_blwf) + current=next + subpos=current + end + end + end + end + current=getnext(current) + end + elseif kind=="pstf" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + if found[getchar(next)] or contextchain(found,next) then + if (not getstate(current) and not getstate(next)) then + setstate(current,s_pstf) + setstate(next,s_pstf) + current=next + postpos=current + end + end + end + end + current=getnext(current) + end + end + end + local current,base,firstcons=start,nil,nil + if getstate(start,s_rphf) then + current=getnext(getnext(start)) + end + if current~=getnext(stop) and getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + current=getnext(current) + if current~=stop then + local char=getchar(current) + if nukta[char] then + current=getnext(current) + char=getchar(current) + end + if char==c_zwj then + local next=getnext(current) + if current~=stop and next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=getnext(next) + local changestop=next==stop + setnext(next) + setstate(current,s_pref) + current=processcharacters(current,font) + setstate(current,s_blwf) + current=processcharacters(current,font) + setstate(current,s_pstf) + current=processcharacters(current,font) + setstate(current,unsetvalue) + if halant[getchar(current)] then + setnext(getnext(current),tmp) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end + else + setnext(current,tmp) + if changestop then + stop=current + end + end + end + end + end + end + else + local last=getnext(stop) + while current~=last do + local next=getnext(current) + if consonant[getchar(current)] then + if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then + if not firstcons then + firstcons=current + end + local a=getstate(current) + if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then + base=current + end + end + end + current=next + end + if not base then + base=firstcons + end + end + if not base then + if getstate(start,s_rphf) then + setstate(start,unsetvalue) + end + return head,stop,nbspaces + else + if getstate(base) then + setstate(base,unsetvalue) + end + basepos=base + end + if not halfpos then + halfpos=base + end + if not subpos then + subpos=base + end + if not postpos then + postpos=subpos or base + end + local moved={} + local current=start + local last=getnext(stop) + while current~=last do + local char=getchar(current) + local target=nil + local cn=getnext(current) + local tpm=twopart_mark[char] + while tpm do + local extra=copy_node(current) + copyinjection(extra,current) + char=tpm[1] + setchar(current,char) + setchar(extra,tpm[2]) + head=insert_node_after(head,current,extra) + tpm=twopart_mark[char] + end + if not moved[current] and dependent_vowel[char] then + if pre_mark[char] then + moved[current]=true + local prev,next=getboth(current) + setlink(prev,next) + if current==stop then + stop=getprev(current) + end + local pos + if before_main[char] then + pos=basepos + else + pos=halfpos + end + local ppos=getprev(pos) + while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do + if getstate(ppos,s_pref) then + pos=ppos + end + ppos=getprev(ppos) + end + local ppos=getprev(pos) + while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and halant[ischar(ppos)] do + ppos=getprev(ppos) + if ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) and consonant[ischar(ppos)] then + pos=ppos + ppos=getprev(ppos) + else + break + end + end + if pos==start then + if head==start then + head=current + end + start=current + end + setlink(getprev(pos),current) + setlink(current,pos) + elseif above_mark[char] then + target=basepos + if subpos==basepos then + subpos=current + end + if postpos==basepos then + postpos=current + end + basepos=current + elseif below_mark[char] then + target=subpos + if postpos==subpos then + postpos=current + end + subpos=current + elseif post_mark[char] then + local n=getnext(postpos) + while n do + local v=ischar(n,font) + if nukta[v] or stress_tone_mark[v] or vowel_modifier[v] then + postpos=n + else + break + end + n=getnext(n) + end + target=postpos + postpos=current + end + if mark_above_below_post[char] then + local prev=getprev(current) + if prev~=target then + local next=getnext(current) + setlink(prev,next) + if current==stop then + stop=prev + end + setlink(current,getnext(target)) + setlink(target,current) + end + end + end + current=cn + end + local current=getnext(start) + local last=getnext(stop) + while current~=last do + local char=getchar(current) + local cn=getnext(current) + if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then + if after_main[ischar(cn)] then + local prev=getprev(current) + local next=getnext(cn) + local bpn=getnext(basepos) + while bpn and dependent_vowel[ischar(bpn)] do + basepos=bpn + bpn=getnext(bpn) + end + if basepos~=prev then + setlink(prev,next) + setlink(cn,getnext(basepos)) + setlink(basepos,current) + if cn==stop then + stop=prev + end + cn=next + end + end + end + current=cn + end + local current=start + local c=nil + while current~=stop do + local char=getchar(current) + if halant[char] or stress_tone_mark[char] then + if not c then + c=current + end + else + c=nil + end + local next=getnext(current) + if c and nukta[getchar(next)] then + if head==c then + head=next + end + if stop==next then + stop=current + end + setlink(getprev(c),next) + local nextnext=getnext(next) + setnext(current,nextnext) + local nextnextnext=getnext(nextnext) + if nextnextnext then + setprev(nextnextnext,current) + end + setlink(nextnext,c) + end + if stop==current then break end + current=getnext(current) + end + if getchar(base)==c_nbsp then + if base==stop then + stop=getprev(stop) + end + nbspaces=nbspaces-1 + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces +end +local separator={} +imerge(separator,consonant) +imerge(separator,independent_vowel) +imerge(separator,dependent_vowel) +imerge(separator,vowel_modifier) +imerge(separator,stress_tone_mark) +for k,v in next,nukta do separator[k]=true end +for k,v in next,halant do separator[k]=true end +local function analyze_next_chars_one(c,font,variant) + local n=getnext(c) + if not n then + return c + end + if variant==1 then + local v=ischar(n,font) + if v and nukta[v] then + n=getnext(n) + if n then + v=ischar(n,font) + end + end + if n and v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv then + if vv==c_zwj and consonant[vvv] then + c=nnn + elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then + local nnnn=getnext(nnn) + if nnnn then + local vvvv=ischar(nnnn,font) + if vvvv and consonant[vvvv] then + c=nnnn + end + end + end + end + end + end + end + end + elseif variant==2 then + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=getnext(c) + if n then + v=ischar(n,font) + if v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv and zw_char[v] then + n=nn + v=vv + nn=getnext(nn) + vv=nn and ischar(nn,font) + end + if vv and halant[v] and consonant[vv] then + c=nn + end + end + end + end + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + local already_pre_mark + local already_above_mark + local already_below_mark + local already_post_mark + while dependent_vowel[v] do + local vowels=twopart_mark[v] or { v } + for k,v in next,vowels do + if pre_mark[v] and not already_pre_mark then + already_pre_mark=true + elseif above_mark[v] and not already_above_mark then + already_above_mark=true + elseif below_mark[v] and not already_below_mark then + already_below_mark=true + elseif post_mark[v] and not already_post_mark then + already_post_mark=true + else + return c + end + end + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if nukta[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if vowel_modifier[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function analyze_next_chars_two(c,font) + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=c + while true do + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + if halant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and zw_char[vvv] then + n=nnn + end + end + elseif vv==c_zwnj or vv==c_zwj then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and halant[vvv] then + n=nnn + end + end + else + break + end + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv and consonant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and nukta[vvv] then + n=nnn + end + end + c=n + else + break + end + else + break + end + else + break + end + else + break + end + end + if not c then + return + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + if anudatta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + if v==c_zwnj or v==c_zwj then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + else + local already_pre_mark + local already_above_mark + local already_below_mark + local already_post_mark + while dependent_vowel[v] do + local vowels=twopart_mark[v] or { v } + for k,v in next,vowels do + if pre_mark[v] and not already_pre_mark then + already_pre_mark=true + elseif above_mark[v] and not already_above_mark then + already_above_mark=true + elseif below_mark[v] and not already_below_mark then + already_below_mark=true + elseif post_mark[v] and not already_post_mark then + already_post_mark=true + else + return c + end + end + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if nukta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if halant[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + end + if vowel_modifier[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function method_one(head,font,attr) + local current=head + local start=true + local done=false + local nbspaces=0 + local syllabe=0 + while current do + local char=ischar(current,font) + if char then + done=true + local syllablestart=current + local syllableend=nil + local c=current + local n=getnext(c) + local first=char + if n and ra[first] then + local second=ischar(n,font) + if second and halant[second] then + local n=getnext(n) + if n then + local third=ischar(n,font) + if third then + c=n + first=third + end + end + end + end + local standalone=first==c_nbsp + if standalone then + local prev=getprev(current) + if prev then + local prevchar=ischar(prev,font) + if not prevchar then + elseif not separator[prevchar] then + else + standalone=false + end + else + end + end + if standalone then + local syllableend=analyze_next_chars_one(c,font,2) + current=getnext(syllableend) + if syllablestart~=syllableend then + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + else + if consonant[char] then + local prevc=true + while prevc do + prevc=false + local n=getnext(current) + if not n then + break + end + local v=ischar(n,font) + if not v then + break + end + if nukta[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + end + if halant[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + if v==c_zwnj or v==c_zwj then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + end + if consonant[v] then + prevc=true + current=n + end + end + end + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and nukta[v] then + current=n + n=getnext(current) + end + end + syllableend=current + current=n + if current then + local v=ischar(current,font) + if not v then + elseif halant[v] then + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and zw_char[v] then + syllableend=n + current=getnext(n) + else + syllableend=current + current=n + end + else + syllableend=current + current=n + end + else + if dependent_vowel[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end + end + end + if syllablestart~=syllableend then + if syllableend then + syllabe=syllabe+1 + local c=syllablestart + local n=getnext(syllableend) + while c~=n do + setprop(c,a_syllabe,syllabe) + c=getnext(c) + end + end + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + elseif independent_vowel[char] then + syllableend=current + current=getnext(current) + if current then + local v=ischar(current,font) + if v then + if vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end + end + end + else + if show_syntax_errors then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) + end + end + current=getnext(current) + end + end + else + current=getnext(current) + end + start=false + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + current=head + local n=0 + while current do + local char=ischar(current,font) + if char then + if n==0 and not getstate(current) then + setstate(current,s_init) + end + n=n+1 + else + n=0 + end + current=getnext(current) + end + return head,done +end +local function method_two(head,font,attr) + local current=head + local start=true + local done=false + local syllabe=0 + local nbspaces=0 + while current do + local syllablestart=nil + local syllableend=nil + local char=ischar(current,font) + if char then + done=true + syllablestart=current + local c=current + local n=getnext(current) + if n and ra[char] then + local nextchar=ischar(n,font) + if nextchar and halant[nextchar] then + local n=getnext(n) + if n then + local nextnextchar=ischar(n,font) + if nextnextchar then + c=n + char=nextnextchar + end + end + end + end + if independent_vowel[char] then + current=analyze_next_chars_one(c,font,1) + syllableend=current + else + local standalone=char==c_nbsp + if standalone then + nbspaces=nbspaces+1 + local p=getprev(current) + if not p then + elseif ischar(p,font) then + elseif not separator[getchar(p)] then + else + standalone=false + end + end + if standalone then + current=analyze_next_chars_one(c,font,2) + syllableend=current + elseif consonant[getchar(current)] then + current=analyze_next_chars_two(current,font) + syllableend=current + end + end + end + if syllableend then + syllabe=syllabe+1 + local c=syllablestart + local n=getnext(syllableend) + while c~=n do + setprop(c,a_syllabe,syllabe) + c=getnext(c) + end + end + if syllableend and syllablestart~=syllableend then + head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) + end + if not syllableend and show_syntax_errors then + local char=ischar(current,font) + if char and not getstate(current) then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) + end + end + end + start=false + current=getnext(current) + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + current=head + local n=0 + while current do + local char=ischar(current,font) + if char then + if n==0 and not getstate(current) then + setstate(current,s_init) + end + n=n+1 + else + n=0 + end + current=getnext(current) + end + return head,done +end +for i=1,nofscripts do + methods[scripts_one[i]]=method_one + methods[scripts_two[i]]=method_two +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl” 797b5c71bf819c5f4fb314a4d646e9a7] --- + +if not modules then modules={} end modules ['font-ocl']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tostring,tonumber,next=tostring,tonumber,next +local round,max=math.round,math.round +local gsub,find=string.gsub,string.find +local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat +local setmetatableindex=table.setmetatableindex +local formatters=string.formatters +local tounicode=fonts.mappings.tounicode +local helpers=fonts.helpers +local charcommand=helpers.commands.char +local rightcommand=helpers.commands.right +local leftcommand=helpers.commands.left +local downcommand=helpers.commands.down +local otf=fonts.handlers.otf +local otfregister=otf.features.register +local f_color=formatters["%.3f %.3f %.3f rg"] +local f_gray=formatters["%.3f g"] +if context then + local startactualtext=nil + local stopactualtext=nil + function otf.getactualtext(s) + if not startactualtext then + startactualtext=backends.codeinjections.startunicodetoactualtextdirect + stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect + end + return startactualtext(s),stopactualtext() + end +else + local tounicode=fonts.mappings.tounicode16 + function otf.getactualtext(s) + return + "/Span << /ActualText >> BDC", + "EMC" + end +end +local sharedpalettes={} +local hash=setmetatableindex(function(t,k) + local v={ "pdf","direct",k } + t[k]=v + return v +end) +if context then + local colors=attributes.list[attributes.private('color')] or {} + local transparencies=attributes.list[attributes.private('transparency')] or {} + function otf.registerpalette(name,values) + sharedpalettes[name]=values + local color=lpdf.color + local transparency=lpdf.transparency + local register=colors.register + for i=1,#values do + local v=values[i] + if v=="textcolor" then + values[i]=false + else + local c=nil + local t=nil + if type(v)=="table" then + c=register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c=colors[v] + t=transparencies[v] + end + if c and t then + values[i]=hash[color(1,c).." "..transparency(t)] + elseif c then + values[i]=hash[color(1,c)] + elseif t then + values[i]=hash[color(1,t)] + end + end + end + end +else + function otf.registerpalette(name,values) + sharedpalettes[name]=values + for i=1,#values do + local v=values[i] + if v then + values[i]=hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end + end + end +end +local function convert(t,k) + local v={} + for i=1,#k do + local p=k[i] + local r,g,b=p[1],p[2],p[3] + if r==g and g==b then + v[i]=hash[f_gray(r/255)] + else + v[i]=hash[f_color(r/255,g/255,b/255)] + end + end + t[k]=v + return v +end +local mode={ "pdf","mode","font" } +local push={ "pdf","page","q" } +local pop={ "pdf","page","Q" } +local function initializeoverlay(tfmdata,kind,value) + if value then + local resources=tfmdata.resources + local palettes=resources.colorpalettes + if palettes then + local converted=resources.converted + if not converted then + converted=setmetatableindex(convert) + resources.converted=converted + end + local colorvalues=sharedpalettes[value] + local default=false + if colorvalues then + default=colorvalues[#colorvalues] + else + colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + end + local classes=#colorvalues + if classes==0 then + return + end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local properties=tfmdata.properties + properties.virtualized=true + tfmdata.fonts={ + { id=0 } + } + local getactualtext=otf.getactualtext + local b,e=getactualtext(tounicode(0xFFFD)) + local actualb={ "pdf","page",b } + local actuale={ "pdf","page",e } + for unicode,character in next,characters do + local description=descriptions[unicode] + if description then + local colorlist=description.colors + if colorlist then + local u=description.unicode or characters[unicode].unicode + local w=character.width or 0 + local s=#colorlist + local goback=w~=0 and leftcommand[w] or nil + local t={ + mode, + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, + } + local n=3 + local l=nil + for i=1,s do + local entry=colorlist[i] + local v=colorvalues[entry.class] or default + if v and l~=v then + n=n+1 t[n]=v + l=v + end + n=n+1 t[n]=charcommand[entry.slot] + if s>1 and i temp-otf-svg-shape.log","w") + end + end + local new=nil + local function inkscapeformat(suffix) + if new==nil then + new=os.resultof("inkscape --version") or "" + new=new=="" or not find(new,"Inkscape%s*0") + end + return new and "filename" or suffix + end + function otfsvg.topdf(svgshapes,tfmdata) + local pdfshapes={} + local inkscape=runner() + if inkscape then + local descriptions=tfmdata.descriptions + local nofshapes=#svgshapes + local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert=formatters["%s --export-%s=%s\n"] + local filterglyph=otfsvg.filterglyph + local nofdone=0 + local processed={} + report_svg("processing %i svg containers",nofshapes) + statistics.starttiming() + for i=1,nofshapes do + local entry=svgshapes[i] + for index=entry.first,entry.last do + local data=filterglyph(entry,index) + if data and data~="" then + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + savedata(svgfile,data) + inkscape:write(f_convert(svgfile,inkscapeformat("pdf"),pdffile)) + processed[index]=true + nofdone=nofdone+1 + if nofdone%25==0 then + report_svg("%i shapes submitted",nofdone) + end + end + end + end + if nofdone%25~=0 then + report_svg("%i shapes submitted",nofdone) + end + report_svg("processing can be going on for a while") + inkscape:write("quit\n") + inkscape:close() + report_svg("processing %i pdf results",nofshapes) + for index in next,processed do + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + local pdfdata=loaddata(pdffile) + if pdfdata and pdfdata~="" then + pdfshapes[index]={ + data=pdfdata, + } + end + remove(svgfile) + remove(pdffile) + end + local characters=tfmdata.characters + for k,v in next,characters do + local d=descriptions[k] + local i=d.index + if i then + local p=pdfshapes[i] + if p then + local w=d.width + local l=d.boundingbox[1] + local r=d.boundingbox[3] + p.scale=(r-l)/w + p.x=l + end + end + end + if not next(pdfshapes) then + report_svg("there are no converted shapes, fix your setup") + end + statistics.stoptiming() + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + end + end + return pdfshapes + end +end +local function initializesvg(tfmdata,kind,value) + if value and otf.svgenabled then + local svg=tfmdata.properties.svg + local hash=svg and svg.hash + local timestamp=svg and svg.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then + local svgfile=containers.read(otf.svgcache,hash) + local svgshapes=svgfile and svgfile.svgshapes + pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"svg") + return true + end +end +otfregister { + name="svg", + description="svg glyphs", + manipulators={ + base=initializesvg, + node=initializesvg, + } +} +local otfpng=otf.png or {} +otf.png=otfpng +otf.pngenabled=true +do + local report_png=logs.reporter("fonts","png conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + local runner=sandbox and sandbox.registerrunner { + name="otfpng", + program="gm", + template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + } + if not runner then + runner=function() + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") + end + end + function otfpng.topdf(pngshapes) + local pdfshapes={} + local pngfile="temp-otf-png-shape.png" + local pdffile="temp-otf-png-shape.pdf" + local nofdone=0 + local indices=sortedkeys(pngshapes) + local nofindices=#indices + report_png("processing %i png containers",nofindices) + statistics.starttiming() + for i=1,nofindices do + local index=indices[i] + local entry=pngshapes[index] + local data=entry.data + local x=entry.x + local y=entry.y + savedata(pngfile,data) + runner() + pdfshapes[index]={ + x=x~=0 and x or nil, + y=y~=0 and y or nil, + data=loaddata(pdffile), + } + nofdone=nofdone+1 + if nofdone%100==0 then + report_png("%i shapes processed",nofdone) + end + end + report_png("processing %i pdf results",nofindices) + remove(pngfile) + remove(pdffile) + statistics.stoptiming() + if statistics.elapsedseconds then + report_png("png conversion time %s",statistics.elapsedseconds() or "-") + end + return pdfshapes + end +end +local function initializepng(tfmdata,kind,value) + if value and otf.pngenabled then + local png=tfmdata.properties.png + local hash=png and png.hash + local timestamp=png and png.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local pngfile=containers.read(otf.pngcache,hash) + local pngshapes=pngfile and pngfile.pngshapes + pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"png") + return true + end +end +otfregister { + name="sbix", + description="sbix glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } +} +otfregister { + name="cblc", + description="cblc glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } +} +if context then + local function initializecolor(tfmdata,kind,value) + if value=="auto" then + return + initializeoverlay(tfmdata,kind,value) or + initializesvg(tfmdata,kind,value) or + initializepng(tfmdata,kind,value) + elseif value=="overlay" then + return initializeoverlay(tfmdata,kind,value) + elseif value=="svg" then + return initializesvg(tfmdata,kind,value) + elseif value=="png" or value=="bitmap" then + return initializepng(tfmdata,kind,value) + else + end + end + otfregister { + name="color", + description="color glyphs", + manipulators={ + base=initializecolor, + node=initializecolor, + } + } +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc” 0f12230ea07b5151f75d52726977e91f] --- + +if not modules then modules={} end modules ['font-otc']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash +local type,next,tonumber=type,next,tonumber +local lpegmatch=lpeg.match +local utfbyte,utflen=utf.byte,utf.len +local sortedhash=table.sortedhash +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local report_otf=logs.reporter("fonts","otf loading") +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local setmetatableindex=table.setmetatableindex +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps +local normalized={ + substitution="substitution", + single="substitution", + ligature="ligature", + alternate="alternate", + multiple="multiple", + kern="kern", + pair="pair", + single="single", + chainsubstitution="chainsubstitution", + chainposition="chainposition", +} +local types={ + substitution="gsub_single", + ligature="gsub_ligature", + alternate="gsub_alternate", + multiple="gsub_multiple", + kern="gpos_pair", + pair="gpos_pair", + single="gpos_single", + chainsubstitution="gsub_contextchain", + chainposition="gpos_contextchain", +} +local names={ + gsub_single="gsub", + gsub_multiple="gsub", + gsub_alternate="gsub", + gsub_ligature="gsub", + gsub_context="gsub", + gsub_contextchain="gsub", + gsub_reversecontextchain="gsub", + gpos_single="gpos", + gpos_pair="gpos", + gpos_cursive="gpos", + gpos_mark2base="gpos", + gpos_mark2ligature="gpos", + gpos_mark2mark="gpos", + gpos_context="gpos", + gpos_contextchain="gpos", +} +setmetatableindex(types,function(t,k) t[k]=k return k end) +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function getrange(sequences,category) + local count=#sequences + local first=nil + local last=nil + for i=1,count do + local t=sequences[i].type + if t and names[t]==category then + if not first then + first=i + end + last=i + end + end + return first or 1,last or count +end +local function validspecification(specification,name) + local dataset=specification.dataset + if dataset then + elseif specification[1] then + dataset=specification + specification={ dataset=dataset } + else + dataset={ { data=specification.data } } + specification.data=nil + specification.dataset=dataset + end + local first=dataset[1] + if first then + first=first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name)~="string" then + name=specification.name or first.name + end + if type(name)~="string" then + report_otf("invalid feature specification, no name") + return + end + local n=#dataset + if n>0 then + for i=1,n do + setmetatableindex(dataset[i],specification) + end + return specification,name + end +end +local function addfeature(data,feature,specifications) + if not specifications then + report_otf("missing specification") + return + end + local descriptions=data.descriptions + local resources=data.resources + local features=resources.features + local sequences=resources.sequences + if not features or not sequences then + report_otf("missing specification") + return + end + local alreadydone=resources.alreadydone + if not alreadydone then + alreadydone={} + resources.alreadydone=alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications]=true + end + local fontfeatures=resources.features or everywhere + local unicodes=resources.unicodes + local splitter=lpeg.splitter(" ",unicodes) + local done=0 + local skip=0 + local aglunicodes=false + local privateslot=fonthelpers.privateslot + local specifications=validspecification(specifications,feature) + if not specifications then + return + end + local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1) + local function tounicode(code) + if not code then + return + end + if type(code)=="number" then + return code + end + local u=unicodes[code] + if u then + return u + end + if utflen(code)==1 then + u=utfbyte(code) + if u then + return u + end + end + if privateslot then + u=privateslot(code) + if u then + return u + end + end + local u=lpegmatch(p,code) + if u then + return u + end + if not aglunicodes then + aglunicodes=fonts.encodings.agl.unicodes + end + local u=aglunicodes[code] + if u then + return u + end + end + local coverup=otf.coverup + local coveractions=coverup.actions + local stepkey=coverup.stepkey + local register=coverup.register + local function prepare_substitution(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(replacement)=="table" then + replacement=replacement[1] + end + replacement=tounicode(replacement) + if replacement and (nocheck or descriptions[replacement]) then + cover(coverage,unicode,replacement) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_alternate(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + for i=1,#replacement do + local u=tounicode(replacement[i]) + r[i]=(nocheck or descriptions[u]) and u or unicode + end + cover(coverage,unicode,r) + done=done+1 + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_multiple(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + local n=0 + for i=1,#replacement do + local u=tounicode(replacement[i]) + if nocheck or descriptions[u] then + n=n+1 + r[n]=u + end + end + if n>0 then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 + end + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function prepare_ligature(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,ligature in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(ligature)=="string" then + ligature={ lpegmatch(splitter,ligature) } + end + local present=true + for i=1,#ligature do + local l=ligature[i] + local u=tounicode(l) + if nocheck or descriptions[u] then + ligature[i]=u + else + present=false + break + end + end + if present then + cover(coverage,unicode,ligature) + done=done+1 + else + skip=skip+1 + end + end + end + return coverage + end + local function resetspacekerns() + data.properties.hasspacekerns=true + data.resources .spacekerns=nil + end + local function prepare_kern(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + local isspace=false + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + return coverage + end + local function prepare_pair(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + if cover then + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end + end + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end + end + if isspace then + resetspacekerns() + end + else + report_otf("unknown cover type %a",featuretype) + end + return coverage + end + local prepare_single=prepare_pair + local function prepare_chain(list,featuretype,sublookups) + local rules=list.rules + local coverage={} + if rules then + local rulehash={} + local rulesize=0 + local lookuptype=types[featuretype] + for nofrules=1,#rules do + local rule=rules[nofrules] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups and sublookups then + for k,v in sortedhash(lookups) do + local t=type(v) + if t=="table" then + for i=1,#v do + local vi=v[i] + if type(vi)~="table" then + v[i]={ vi } + end + end + elseif t=="number" then + local lookup=sublookups[v] + if lookup then + lookups[k]={ lookup } + if not subtype then + subtype=lookup.type + end + elseif v==0 then + lookups[k]={ { type="gsub_remove" } } + else + lookups[k]=false + end + else + lookups[k]=false + end + end + end + if nofsequences>0 then + local hashed={} + for i=1,nofsequences do + local t={} + local s=sequence[i] + for i=1,#s do + local u=tounicode(s[i]) + if u then + t[u]=true + end + end + hashed[i]=t + end + sequence=hashed + rulesize=rulesize+1 + rulehash[rulesize]={ + nofrules, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + for unic in sortedhash(sequence[start]) do + local cu=coverage[unic] + if not cu then + coverage[unic]=rulehash + end + end + sequence.n=nofsequences + end + end + rulehash.n=rulesize + end + return coverage + end + local dataset=specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + local function inject(specification,sequences,sequence,first,last,category,name) + local position=specification.position or false + if not position then + position=specification.prepend + if position==true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) + return + end + end + if not position then + position=specification.append + if position==true then + if trace_loading then + report(name,category,last+1,first,last,sequences) + end + insert(sequences,last+1,sequence) + return + end + end + local kind=type(position) + if kind=="string" then + local index=false + for i=first,last do + local s=sequences[i] + local f=s.features + if f then + for k in sortedhash(f) do + if k==position then + index=i + break + end + end + if index then + break + end + end + end + if index then + position=index + else + position=last+1 + end + elseif kind=="number" then + if position<0 then + position=last-position+1 + end + if position>last then + position=last+1 + elseif position0 then + for k,v in next,askedfeatures do + if v[1] then + askedfeatures[k]=tohash(v) + end + end + if featureflags[1] then featureflags[1]="mark" end + if featureflags[2] then featureflags[2]="ligature" end + if featureflags[3] then featureflags[3]="base" end + local steptype=types[featuretype] + local sequence={ + chain=featurechain, + features={ [feature]=askedfeatures }, + flags=featureflags, + name=feature, + order=featureorder, + [stepkey]=steps, + nofsteps=nofsteps, + type=steptype, + } + checkflags(sequence,resources) + checkmerge(sequence) + checksteps(sequence) + local first,last=getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) + local features=fontfeatures[category] + if not features then + features={} + fontfeatures[category]=features + end + local k=features[feature] + if not k then + k={} + features[feature]=k + end + for script,languages in next,askedfeatures do + local kk=k[script] + if not kk then + kk={} + k[script]=kk + end + for language,value in next,languages do + kk[language]=value + end + end + end + end + end + if trace_loading then + report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) + end +end +otf.enhancers.addfeature=addfeature +local extrafeatures={} +local knownfeatures={} +function otf.addfeature(name,specification) + if type(name)=="table" then + specification=name + end + if type(specification)~="table" then + report_otf("invalid feature specification, no valid table") + return + end + specification,name=validspecification(specification,name) + if name and specification then + local slot=knownfeatures[name] + if not slot then + slot=#extrafeatures+1 + knownfeatures[name]=slot + elseif specification.overload==false then + slot=#extrafeatures+1 + knownfeatures[name]=slot + else + end + specification.name=name + extrafeatures[slot]=specification + end +end +local function enhance(data,filename,raw) + for slot=1,#extrafeatures do + local specification=extrafeatures[slot] + addfeature(data,specification.name,specification) + end +end +otf.enhancers.enhance=enhance +otf.enhancers.register("check extra features",enhance) + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] --- + +if not modules then modules={} end modules ['font-onr']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers +local next,type,tonumber,rawset=next,type,tonumber,rawset +local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find +local char,byte,sub=string.char,string.byte,string.sub +local abs=math.abs +local bxor,rshift=bit32.bxor,bit32.rshift +local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc +local lpegmatch,patterns=lpeg.match,lpeg.patterns +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local report_afm=logs.reporter("fonts","afm loading") +local report_pfb=logs.reporter("fonts","pfb loading") +local handlers=fonts.handlers +local afm=handlers.afm or {} +handlers.afm=afm +local readers=afm.readers or {} +afm.readers=readers +afm.version=1.513 +local get_indexes,get_shapes +do + local decrypt + do + local r,c1,c2,n=0,0,0,0 + local function step(c) + local cipher=byte(c) + local plain=bxor(cipher,rshift(r,8)) + r=((cipher+r)*c1+c2)%65536 + return char(plain) + end + decrypt=function(binary,initial,seed) + r,c1,c2,n=initial,52845,22719,seed + binary=gsub(binary,".",step) + return sub(binary,n+1) + end + end + local charstrings=P("/CharStrings") + local subroutines=P("/Subrs") + local encoding=P("/Encoding") + local dup=P("dup") + local put=P("put") + local array=P("array") + local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) + local digits=R("09")^1 + local cardinal=digits/tonumber + local spaces=P(" ")^1 + local spacing=patterns.whitespace^0 + local routines,vector,chars,n,m + local initialize=function(str,position,size) + n=0 + m=size + return position+1 + end + local setroutine=function(str,position,index,size,filename) + if routines[index] then + return false + end + local forward=position+size + local stream=decrypt(sub(str,position+1,forward),4330,4) + routines[index]={ byte(stream,1,#stream) } + n=n+1 + if n>=m then + return #str + end + return forward+1 + end + local setvector=function(str,position,name,size,filename) + local forward=position+tonumber(size) + if n>=m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + return forward + else + return #str + end + end + local setshapes=function(str,position,name,size,filename) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + if n>m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + chars [n]=decrypt(stream,4330,4) + return forward + else + return #str + end + end + local p_rd=spacing*(P("RD")+P("-|")) + local p_np=spacing*(P("NP")+P("|")) + local p_nd=spacing*(P("ND")+P("|")) + local p_filterroutines= + (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1 + local p_filtershapes= + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 + local p_filternames=Ct ( + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 + ) + local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( + Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 +,rawset) + local key=spacing*P("/")*R("az","AZ") + local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") } + local num=spacing*(R("09")+S("+-."))^1/tonumber + local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}")) + local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false)) + local nam=spacing*P("/")*Cs(R("az","AZ")^1) + local p_filtermetadata=( + P("/")*Carg(1)*(( + C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr + ) )/function(t,k,v) t[lower(k)]=v end+P(1) + )^0*Carg(1) + local function loadpfbvector(filename,shapestoo,streams) + local data=io.loaddata(resolvers.findfile(filename)) + if not data then + report_pfb("no data in %a",filename) + return + end + if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then + report_pfb("no font in %a",filename) + return + end + local ascii,binary=match(data,"(.*)eexec%s+......(.*)") + if not binary then + report_pfb("no binary data in %a",filename) + return + end + binary=decrypt(binary,55665,4) + local names={} + local encoding=lpegmatch(p_filterencoding,ascii) + local metadata=lpegmatch(p_filtermetadata,ascii,1,{}) + local glyphs={} + routines,vector,chars={},{},{} + if shapestoo or streams then + lpegmatch(p_filterroutines,binary,1,filename) + lpegmatch(p_filtershapes,binary,1,filename) + local data={ + dictionaries={ + { + charstrings=chars, + charset=vector, + subroutines=routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams,true) + else + lpegmatch(p_filternames,binary,1,filename) + end + names=vector + routines,vector,chars=nil,nil,nil + return names,encoding,glyphs,metadata + end + local pfb=handlers.pfb or {} + handlers.pfb=pfb + pfb.loadvector=loadpfbvector + get_indexes=function(data,pfbname) + local vector=loadpfbvector(pfbname) + if vector then + local characters=data.characters + if trace_loading then + report_afm("getting index data from %a",pfbname) + end + for index=0,#vector do + local name=vector[index] + local char=characters[name] + if char then + if trace_indexing then + report_afm("glyph %a has index %a",name,index) + end + char.index=index + else + if trace_indexing then + report_afm("glyph %a has index %a but no data",name,index) + end + end + end + end + end + get_shapes=function(pfbname) + local vector,encoding,glyphs=loadpfbvector(pfbname,true) + return glyphs + end +end +local spacer=patterns.spacer +local whitespace=patterns.whitespace +local lineend=patterns.newline +local spacing=spacer^0 +local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber +local name=spacing*C((1-whitespace)^1) +local words=spacing*((1-lineend)^1/strip) +local rest=(1-lineend)^0 +local fontdata=Carg(1) +local semicolon=spacing*P(";") +local plus=spacing*P("plus")*number +local minus=spacing*P("minus")*number +local function addkernpair(data,one,two,value) + local chr=data.characters[one] + if chr then + local kerns=chr.kerns + if kerns then + kerns[two]=tonumber(value) + else + chr.kerns={ [two]=tonumber(value) } + end + end +end +local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair +local chr=false +local ind=0 +local function start(data,version) + data.metadata.afmversion=version + ind=0 + chr={} +end +local function stop() + ind=0 + chr=false +end +local function setindex(i) + if i<0 then + ind=ind+1 + else + ind=i + end + chr={ + index=ind + } +end +local function setwidth(width) + chr.width=width +end +local function setname(data,name) + data.characters[name]=chr +end +local function setboundingbox(boundingbox) + chr.boundingbox=boundingbox +end +local function setligature(plus,becomes) + local ligatures=chr.ligatures + if ligatures then + ligatures[plus]=becomes + else + chr.ligatures={ [plus]=becomes } + end +end +local p_charmetric=(( + P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature + )*semicolon )^1 +local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics") +local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) +local function set_1(data,key,a) data.metadata[lower(key)]=a end +local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end +local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end +local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value) + data.metadata[key]=value + end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) + data.metadata[key]=value + end+fontdata*P("IsFixedPitch")*name/function(data,pitch) + data.metadata.monospaced=toboolean(pitch,true) + end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) + data.metadata.boundingbox=boundingbox + end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) + data.metadata[key]=value + end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 ++(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 ++(fontdata*C("CHECKSUM")*number*words*rest)/set_1 ++(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 ++(fontdata*C("QUAD")*number*rest)/set_1 ++(fontdata*C("EXTRASPACE")*number*rest)/set_1 ++(fontdata*C("NUM")*number*number*number*rest)/set_3 ++(fontdata*C("DENOM")*number*number*rest)/set_2 ++(fontdata*C("SUP")*number*number*number*rest)/set_3 ++(fontdata*C("SUB")*number*number*rest)/set_2 ++(fontdata*C("SUPDROP")*number*rest)/set_1 ++(fontdata*C("SUBDROP")*number*rest)/set_1 ++(fontdata*C("DELIM")*number*number*rest)/set_2 ++(fontdata*C("AXISHEIGHT")*number*rest)/set_1 + ) +local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) +local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) +local function read(filename,parser) + local afmblob=io.loaddata(filename) + if afmblob then + local data={ + resources={ + filename=resolvers.unresolve(filename), + version=afm.version, + creator="context mkiv", + }, + properties={ + hasitalics=false, + }, + goodies={}, + metadata={ + filename=file.removesuffix(file.basename(filename)) + }, + characters={ + }, + descriptions={ + }, + } + if trace_loading then + report_afm("parsing afm file %a",filename) + end + lpegmatch(parser,afmblob,1,data) + return data + else + if trace_loading then + report_afm("no valid afm file %a",filename) + end + return nil + end +end +function readers.loadfont(afmname,pfbname) + local data=read(resolvers.findfile(afmname),fullparser) + if data then + if not pfbname or pfbname=="" then + pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) + end + if pfbname and pfbname~="" then + data.resources.filename=resolvers.unresolve(pfbname) + get_indexes(data,pfbname) + return data + else + report_afm("no pfb file for %a",afmname) + end + end +end +function readers.loadshapes(filename) + local fullname=resolvers.findfile(filename) or "" + if fullname=="" then + return { + filename="not found: "..filename, + glyphs={} + } + else + return { + filename=fullname, + format="opentype", + glyphs=get_shapes(fullname) or {}, + units=1000, + } + end +end +function readers.getinfo(filename) + local data=read(resolvers.findfile(filename),infoparser) + if data then + return data.metadata + end +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one” 53cd565030e919da984b50471cc3be37] --- + +if not modules then modules={} end modules ['font-one']={ + version=1.001, + optimize=true, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers +local next,type,tonumber,rawget=next,type,tonumber,rawget +local match,gsub=string.match,string.gsub +local abs=math.abs +local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg +local lpegmatch,patterns=lpeg.match,lpeg.patterns +local sortedhash=table.sortedhash +local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local report_afm=logs.reporter("fonts","afm loading") +local setmetatableindex=table.setmetatableindex +local derivetable=table.derive +local findbinfile=resolvers.findbinfile +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local definers=fonts.definers +local readers=fonts.readers +local constructors=fonts.constructors +local afm=constructors.handlers.afm +local pfb=constructors.handlers.pfb +local otf=fonts.handlers.otf +local otfreaders=otf.readers +local otfenhancers=otf.enhancers +local afmfeatures=constructors.features.afm +local registerafmfeature=afmfeatures.register +local afmenhancers=constructors.enhancers.afm +local registerafmenhancer=afmenhancers.register +afm.version=1.513 +afm.cache=containers.define("fonts","one",afm.version,true) +afm.autoprefixed=true +afm.helpdata={} +afm.syncspace=true +local overloads=fonts.mappings.overloads +local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes +function afm.load(filename) + filename=resolvers.findfile(filename,'afm') or "" + if filename~="" and not fonts.names.ignoredfile(filename) then + local name=file.removesuffix(file.basename(filename)) + local data=containers.read(afm.cache,name) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local pfbfile=file.replacesuffix(name,"pfb") + local pfbname=resolvers.findfile(pfbfile,"pfb") or "" + if pfbname=="" then + pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" + end + local pfbsize=0 + local pfbtime=0 + if pfbname~="" then + local attr=lfs.attributes(pfbname) + pfbsize=attr.size or 0 + pfbtime=attr.modification or 0 + end + if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then + report_afm("reading %a",filename) + data=afm.readers.loadfont(filename,pfbname) + if data then + afmenhancers.apply(data,filename) + fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) + otfreaders.pack(data) + data.size=size + data.time=time + data.pfbsize=pfbsize + data.pfbtime=pfbtime + report_afm("saving %a in cache",name) + data=containers.write(afm.cache,name,data) + data=containers.read(afm.cache,name) + end + end + if data then + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + end + return data + end +end +local uparser=fonts.mappings.makenameparser() +local function enhance_unify_names(data,filename) + local unicodevector=fonts.encodings.agl.unicodes + local unicodes={} + local names={} + local private=data.private or privateoffset + local descriptions=data.descriptions + for name,blob in sortedhash(data.characters) do + local code=unicodevector[name] + if not code then + code=lpegmatch(uparser,name) + if type(code)~="number" then + code=private + private=private+1 + report_afm("assigning private slot %U for unknown glyph name %a",code,name) + end + end + local index=blob.index + unicodes[name]=code + names[name]=index + blob.name=name + descriptions[code]={ + boundingbox=blob.boundingbox, + width=blob.width, + kerns=blob.kerns, + index=index, + name=name, + } + end + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local krn={} + for name,kern in next,kerns do + local unicode=unicodes[name] + if unicode then + krn[unicode]=kern + else + end + end + description.kerns=krn + end + end + data.characters=nil + data.private=private + local resources=data.resources + local filename=resources.filename or file.removesuffix(file.basename(filename)) + resources.filename=resolvers.unresolve(filename) + resources.unicodes=unicodes + resources.marks={} +end +local everywhere={ ["*"]={ ["*"]=true } } +local noflags={ false,false,false,false } +local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local extrakerns=setmetatableindex("table") + for u,c in next,data.descriptions do + local l=c.ligatures + local k=c.kerns + local e=c.extrakerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + if e then + extrakerns[u]=e + for u,v in next,e do + e[u]=v + end + c.extrakerns=nil + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } + end + if next(extrakerns) then + features.gpos.extrakerns=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + extrakerns=everywhere, + }, + flags=noflags, + name="p_s_1", + nofsteps=1, + order={ "extrakerns" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=extrakerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences +end +local function enhance_fix_names(data) + for k,v in next,data.descriptions do + local n=v.name + local r=overloads[n] + if r then + local name=r.name + if trace_indexing then + report_afm("renaming characters %a to %a",n,name) + end + v.name=name + v.unicode=r.unicode + end + end +end +local addthem=function(rawdata,ligatures) + if ligatures then + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + for ligname,ligdata in next,ligatures do + local one=descriptions[unicodes[ligname]] + if one then + for _,pair in next,ligdata do + local two=unicodes[pair[1]] + local three=unicodes[pair[2]] + if two and three then + local ol=one.ligatures + if ol then + if not ol[two] then + ol[two]=three + end + else + one.ligatures={ [two]=three } + end + end + end + end + end + end +end +local function enhance_add_ligatures(rawdata) + addthem(rawdata,afm.helpdata.ligatures) +end +local function enhance_add_extra_kerns(rawdata) + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + local function do_it_left(what) + if what then + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local extrakerns + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local ks=kerns[simple] + if ks and not kerns[complex] then + if extrakerns then + extrakerns[complex]=ks + else + extrakerns={ [complex]=ks } + end + end + end + end + if extrakerns then + description.extrakerns=extrakerns + end + end + end + end + end + local function do_it_copy(what) + if what then + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local complexdescription=descriptions[complex] + if complexdescription then + local simpledescription=descriptions[complex] + if simpledescription then + local extrakerns + local kerns=simpledescription.kerns + if kerns then + for unicode,kern in next,kerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end + end + end + local extrakerns=simpledescription.extrakerns + if extrakerns then + for unicode,kern in next,extrakerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end + end + end + if extrakerns then + complexdescription.extrakerns=extrakerns + end + end + end + end + end + end + end + do_it_left(afm.helpdata.leftkerned) + do_it_left(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.rightkerned) +end +local function adddimensions(data) + if data then + for unicode,description in next,data.descriptions do + local bb=description.boundingbox + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then + else + description.height=ht + end + if dp==0 or dp<0 then + else + description.depth=dp + end + end + end + end +end +local function copytotfm(data) + if data and data.descriptions then + local metadata=data.metadata + local resources=data.resources + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local unicodes=resources.unicodes + for unicode,description in next,data.descriptions do + characters[unicode]={} + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname or metadata.fullname + local fullname=metadata.fullname or metadata.fontname + local endash=0x2013 + local emdash=0x2014 + local space=0x0020 + local spacer="space" + local spaceunits=500 + local monospaced=metadata.monospaced + local charwidth=metadata.charwidth + local italicangle=metadata.italicangle + local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight + properties.monospaced=monospaced + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + local d_endash=descriptions[endash] + local d_emdash=descriptions[emdash] + local d_space=descriptions[space] + if not d_space or d_space==0 then + d_space=d_endash + end + if d_space then + spaceunits,spacer=d_space.width or 0,"space" + end + if properties.monospaced then + if spaceunits==0 and d_emdash then + spaceunits,spacer=d_emdash.width or 0,"emdash" + end + else + if spaceunits==0 and d_endash then + spaceunits,spacer=d_emdash.width or 0,"endash" + end + end + if spaceunits==0 and charwidth then + spaceunits,spacer=charwidth or 0,"charwidth" + end + if spaceunits==0 then + spaceunits=tonumber(spaceunits) or 500 + end + if spaceunits==0 then + spaceunits=500 + end + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=500 + parameters.space_shrink=333 + parameters.x_height=400 + parameters.quad=1000 + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif afm.syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + if metadata.sup then + local dummy={ 0,0,0 } + parameters[ 1]=metadata.designsize or 0 + parameters[ 2]=metadata.checksum or 0 + parameters[ 3], + parameters[ 4], + parameters[ 5]=unpack(metadata.space or dummy) + parameters[ 6]=metadata.quad or 0 + parameters[ 7]=metadata.extraspace or 0 + parameters[ 8], + parameters[ 9], + parameters[10]=unpack(metadata.num or dummy) + parameters[11], + parameters[12]=unpack(metadata.denom or dummy) + parameters[13], + parameters[14], + parameters[15]=unpack(metadata.sup or dummy) + parameters[16], + parameters[17]=unpack(metadata.sub or dummy) + parameters[18]=metadata.supdrop or 0 + parameters[19]=metadata.subdrop or 0 + parameters[20], + parameters[21]=unpack(metadata.delim or dummy) + parameters[22]=metadata.axisheight or 0 + end + parameters.designsize=(metadata.designsize or 10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=1000 + properties.spacer=spacer + properties.format=fonts.formats[filename] or "type1" + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=fullname + properties.name=filename or fullname or fontname + properties.private=properties.private or data.private or privateoffset +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end + if next(characters) then + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end + end + return nil +end +function afm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) + if okay then + return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) + else + return {} + end +end +local function addtables(data) + local resources=data.resources + local lookuptags=resources.lookuptags + local unicodes=resources.unicodes + if not lookuptags then + lookuptags={} + resources.lookuptags=lookuptags + end + setmetatableindex(lookuptags,function(t,k) + local v=type(k)=="number" and ("lookup "..k) or k + t[k]=v + return v + end) + if not unicodes then + unicodes={} + resources.unicodes=unicodes + setmetatableindex(unicodes,function(t,k) + setmetatableindex(unicodes,nil) + for u,d in next,data.descriptions do + local n=d.name + if n then + t[n]=u + end + end + return rawget(t,k) + end) + end + constructors.addcoreunicodes(unicodes) +end +local function afmtotfm(specification) + local afmname=specification.filename or specification.name + if specification.forced=="afm" or specification.format=="afm" then + if trace_loading then + report_afm("forcing afm format for %a",afmname) + end + else + local tfmname=findbinfile(afmname,"ofm") or "" + if tfmname~="" then + if trace_loading then + report_afm("fallback from afm to tfm for %a",afmname) + end + return + end + end + if afmname~="" then + local features=constructors.checkedfeatures("afm",specification.features.normal) + specification.features.normal=features + constructors.hashinstance(specification,true) + specification=definers.resolve(specification) + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + local rawdata=afm.load(afmname) + if rawdata and next(rawdata) then + addtables(rawdata) + adddimensions(rawdata) + tfmdata=copytotfm(rawdata) + if tfmdata and next(tfmdata) then + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared + end + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=afm.setfeatures(tfmdata,features) + end + elseif trace_loading then + report_afm("no (valid) afm file found with name %a",afmname) + end + tfmdata=containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata + end +end +local function read_from_afm(specification) + local tfmdata=afmtotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) + fonts.loggers.register(tfmdata,'afm',specification) + end + return tfmdata +end +registerafmfeature { + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } +} +registerafmfeature { + name="features", + description="features", + default=true, + initializers={ + node=otf.nodemodeinitializer, + base=otf.basemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } +} +fonts.formats.afm="type1" +fonts.formats.pfb="type1" +local function check_afm(specification,fullname) + local foundname=findbinfile(fullname,'afm') or "" + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"afm") or "" + end + if fullname and foundname=="" and afm.autoprefixed then + local encoding,shortname=match(fullname,"^(.-)%-(.*)$") + if encoding and shortname and fonts.encodings.known[encoding] then + shortname=findbinfile(shortname,'afm') or "" + if shortname~="" then + foundname=shortname + if trace_defining then + report_afm("stripping encoding prefix from filename %a",afmname) + end + end + end + end + if foundname~="" then + specification.filename=foundname + specification.format="afm" + return read_from_afm(specification) + end +end +function readers.afm(specification,method) + local fullname=specification.filename or "" + local tfmdata=nil + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + tfmdata=check_afm(specification,specification.name.."."..forced) + end + if not tfmdata then + local check_tfm=readers.check_tfm + method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" + if method=="tfm" then + tfmdata=check_tfm(specification,specification.name) + elseif method=="afm" then + tfmdata=check_afm(specification,specification.name) + elseif method=="tfm or afm" then + tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) + else + tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) + end + end + else + tfmdata=check_afm(specification,fullname) + end + return tfmdata +end +function readers.pfb(specification,method) + local original=specification.specification + if trace_defining then + report_afm("using afm reader for %a",original) + end + specification.forced="afm" + local function swap(name) + local value=specification[swap] + if value then + specification[swap]=gsub("%.pfb",".afm",1) + end + end + swap("filename") + swap("fullname") + swap("forcedname") + swap("specification") + return readers.afm(specification,method) +end +registerafmenhancer("unify names",enhance_unify_names) +registerafmenhancer("add ligatures",enhance_add_ligatures) +registerafmenhancer("add extra kerns",enhance_add_extra_kerns) +registerafmenhancer("normalize features",enhance_normalize_features) +registerafmenhancer("check extra features",otfenhancers.enhance) +registerafmenhancer("fix names",enhance_fix_names) + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] --- + +if not modules then modules={} end modules ['font-afk']={ + version=1.001, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", + dataonly=true, +} +local allocate=utilities.storage.allocate +fonts.handlers.afm.helpdata={ + ligatures=allocate { + ['f']={ + { 'f','ff' }, + { 'i','fi' }, + { 'l','fl' }, + }, + ['ff']={ + { 'i','ffi' } + }, + ['fi']={ + { 'i','fii' } + }, + ['fl']={ + { 'i','fli' } + }, + ['s']={ + { 't','st' } + }, + ['i']={ + { 'j','ij' } + }, + }, + texligatures=allocate { + ['quoteleft']={ + { 'quoteleft','quotedblleft' } + }, + ['quoteright']={ + { 'quoteright','quotedblright' } + }, + ['hyphen']={ + { 'hyphen','endash' } + }, + ['endash']={ + { 'hyphen','emdash' } + } + }, + leftkerned=allocate { + AEligature="A",aeligature="a", + OEligature="O",oeligature="o", + IJligature="I",ijligature="i", + AE="A",ae="a", + OE="O",oe="o", + IJ="I",ij="i", + Ssharp="S",ssharp="s", + }, + rightkerned=allocate { + AEligature="E",aeligature="e", + OEligature="E",oeligature="e", + IJligature="J",ijligature="j", + AE="E",ae="e", + OE="E",oe="e", + IJ="J",ij="j", + Ssharp="S",ssharp="s", + }, + bothkerned=allocate { + Acircumflex="A",acircumflex="a", + Ccircumflex="C",ccircumflex="c", + Ecircumflex="E",ecircumflex="e", + Gcircumflex="G",gcircumflex="g", + Hcircumflex="H",hcircumflex="h", + Icircumflex="I",icircumflex="i", + Jcircumflex="J",jcircumflex="j", + Ocircumflex="O",ocircumflex="o", + Scircumflex="S",scircumflex="s", + Ucircumflex="U",ucircumflex="u", + Wcircumflex="W",wcircumflex="w", + Ycircumflex="Y",ycircumflex="y", + Agrave="A",agrave="a", + Egrave="E",egrave="e", + Igrave="I",igrave="i", + Ograve="O",ograve="o", + Ugrave="U",ugrave="u", + Ygrave="Y",ygrave="y", + Atilde="A",atilde="a", + Itilde="I",itilde="i", + Otilde="O",otilde="o", + Utilde="U",utilde="u", + Ntilde="N",ntilde="n", + Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", + Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", + Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", + Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", + Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", + Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", + Aacute="A",aacute="a", + Cacute="C",cacute="c", + Eacute="E",eacute="e", + Iacute="I",iacute="i", + Lacute="L",lacute="l", + Nacute="N",nacute="n", + Oacute="O",oacute="o", + Racute="R",racute="r", + Sacute="S",sacute="s", + Uacute="U",uacute="u", + Yacute="Y",yacute="y", + Zacute="Z",zacute="z", + Dstroke="D",dstroke="d", + Hstroke="H",hstroke="h", + Tstroke="T",tstroke="t", + Cdotaccent="C",cdotaccent="c", + Edotaccent="E",edotaccent="e", + Gdotaccent="G",gdotaccent="g", + Idotaccent="I",idotaccent="i", + Zdotaccent="Z",zdotaccent="z", + Amacron="A",amacron="a", + Emacron="E",emacron="e", + Imacron="I",imacron="i", + Omacron="O",omacron="o", + Umacron="U",umacron="u", + Ccedilla="C",ccedilla="c", + Kcedilla="K",kcedilla="k", + Lcedilla="L",lcedilla="l", + Ncedilla="N",ncedilla="n", + Rcedilla="R",rcedilla="r", + Scedilla="S",scedilla="s", + Tcedilla="T",tcedilla="t", + Ohungarumlaut="O",ohungarumlaut="o", + Uhungarumlaut="U",uhungarumlaut="u", + Aogonek="A",aogonek="a", + Eogonek="E",eogonek="e", + Iogonek="I",iogonek="i", + Uogonek="U",uogonek="u", + Aring="A",aring="a", + Uring="U",uring="u", + Abreve="A",abreve="a", + Ebreve="E",ebreve="e", + Gbreve="G",gbreve="g", + Ibreve="I",ibreve="i", + Obreve="O",obreve="o", + Ubreve="U",ubreve="u", + Ccaron="C",ccaron="c", + Dcaron="D",dcaron="d", + Ecaron="E",ecaron="e", + Lcaron="L",lcaron="l", + Ncaron="N",ncaron="n", + Rcaron="R",rcaron="r", + Scaron="S",scaron="s", + Tcaron="T",tcaron="t", + Zcaron="Z",zcaron="z", + dotlessI="I",dotlessi="i", + dotlessJ="J",dotlessj="j", + AEligature="AE",aeligature="ae",AE="AE",ae="ae", + OEligature="OE",oeligature="oe",OE="OE",oe="oe", + IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", + Lstroke="L",lstroke="l",Lslash="L",lslash="l", + Ostroke="O",ostroke="o",Oslash="O",oslash="o", + Ssharp="SS",ssharp="ss", + Aumlaut="A",aumlaut="a", + Eumlaut="E",eumlaut="e", + Iumlaut="I",iumlaut="i", + Oumlaut="O",oumlaut="o", + Uumlaut="U",uumlaut="u", + } +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] --- + +if not modules then modules={} end modules ['luatex-fonts-tfm']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local match,format=string.match,string.format +local concat,sortedhash=table.concat,table.sortedhash +local idiv=number.idiv +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) +local report_defining=logs.reporter("fonts","defining") +local report_tfm=logs.reporter("fonts","tfm loading") +local findbinfile=resolvers.findbinfile +local setmetatableindex=table.setmetatableindex +local fonts=fonts +local handlers=fonts.handlers +local helpers=fonts.helpers +local readers=fonts.readers +local constructors=fonts.constructors +local encodings=fonts.encodings +local tfm=constructors.handlers.tfm +tfm.version=1.000 +tfm.maxnestingdepth=5 +tfm.maxnestingsize=65536*1024 +local otf=fonts.handlers.otf +local otfenhancers=otf.enhancers +local tfmfeatures=constructors.features.tfm +local registertfmfeature=tfmfeatures.register +local tfmenhancers=constructors.enhancers.tfm +local registertfmenhancer=tfmenhancers.register +local charcommand=helpers.commands.char +constructors.resolvevirtualtoo=false +fonts.formats.tfm="type1" +fonts.formats.ofm="type1" +function tfm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) + if okay then + return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) + else + return {} + end +end +local depth={} +local loadtfm=font.read_tfm +local loadvf=font.read_vf +local function read_from_tfm(specification) + local filename=specification.filename + local size=specification.size + depth[filename]=(depth[filename] or 0)+1 + if trace_defining then + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata=loadtfm(filename,size) + if tfmdata then + local features=specification.features and specification.features.normal or {} + local features=constructors.checkedfeatures("tfm",features) + specification.features.normal=features + local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata=newtfmdata + end + local resources=tfmdata.resources or {} + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + local shared=tfmdata.shared or {} + shared.features=features + shared.resources=resources + properties.name=tfmdata.name + properties.fontname=tfmdata.fontname + properties.psname=tfmdata.psname + properties.fullname=tfmdata.fullname + properties.filename=specification.filename + properties.format=tfmdata.format or fonts.formats.tfm + properties.usedbitmap=tfmdata.usedbitmap + tfmdata.properties=properties + tfmdata.resources=resources + tfmdata.parameters=parameters + tfmdata.shared=shared + shared.rawdata={ resources=resources } + shared.features=features + if newtfmdata then + if not resources.marks then + resources.marks={} + end + if not resources.sequences then + resources.sequences={} + end + if not resources.features then + resources.features={ + gsub={}, + gpos={}, + } + end + if not tfmdata.changed then + tfmdata.changed={} + end + if not tfmdata.descriptions then + tfmdata.descriptions=tfmdata.characters + end + otf.readers.addunicodetable(tfmdata) + tfmenhancers.apply(tfmdata,filename) + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + otf.readers.unifymissing(tfmdata) + fonts.mappings.addtounicode(tfmdata,filename) + tfmdata.tounicode=1 + local tounicode=fonts.mappings.tounicode + for unicode,v in next,tfmdata.characters do + local u=v.unicode + if u then + v.tounicode=tounicode(u) + end + end + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil + if size<0 then + size=idiv(65536*-size,100) + end + parameters.factor=1 + parameters.units=1000 + parameters.size=size + parameters.slant=parameters.slant or parameters[1] or 0 + parameters.space=parameters.space or parameters[2] or 0 + parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 + parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 + parameters.x_height=parameters.x_height or parameters[5] or 0 + parameters.quad=parameters.quad or parameters[6] or 0 + parameters.extra_space=parameters.extra_space or parameters[7] or 0 + constructors.enhanceparameters(parameters) + properties.private=properties.private or tfmdata.private or privateoffset + if newtfmdata then + elseif constructors.resolvevirtualtoo then + fonts.loggers.register(tfmdata,file.suffix(filename),specification) + local vfname=findbinfile(specification.name,'ovf') + if vfname and vfname~="" then + local vfdata=loadvf(vfname,size) + if vfdata then + local chars=tfmdata.characters + for k,v in next,vfdata.characters do + chars[k].commands=v.commands + end + properties.virtualized=true + tfmdata.fonts=vfdata.fonts + tfmdata.type="virtual" + local fontlist=vfdata.fonts + local name=file.nameonly(filename) + for i=1,#fontlist do + local n=fontlist[i].name + local s=fontlist[i].size + local d=depth[filename] + s=constructors.scaled(s,vfdata.designsize) + if d>tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i]={ id=0 } + elseif (d>1) and (s>tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i]={ id=0 } + else + local t,id=constructors.readanddefine(n,s) + fontlist[i]={ id=id } + end + end + end + end + end + properties.haskerns=true + properties.hasligatures=true + properties.hasitalics=true + resources.unicodes={} + resources.lookuptags={} + depth[filename]=depth[filename]-1 + return tfmdata + else + depth[filename]=depth[filename]-1 + end +end +local function check_tfm(specification,fullname) + local foundname=findbinfile(fullname,'tfm') or "" + if foundname=="" then + foundname=findbinfile(fullname,'ofm') or "" + end + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"tfm") or "" + end + if foundname~="" then + specification.filename=foundname + specification.format="ofm" + return read_from_tfm(specification) + elseif trace_defining then + report_defining("loading tfm with name %a fails",specification.name) + end +end +readers.check_tfm=check_tfm +function readers.tfm(specification) + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name + end + end + return check_tfm(specification,fullname) +end +readers.ofm=readers.tfm +do + local outfiles={} + local tfmcache=table.setmetatableindex(function(t,tfmdata) + local id=font.define(tfmdata) + t[tfmdata]=id + return id + end) + local encdone=table.setmetatableindex("table") + function tfm.reencode(tfmdata,specification) + local features=specification.features + if not features then + return + end + local features=features.normal + if not features then + return + end + local tfmfile=file.basename(tfmdata.name) + local encfile=features.reencode + local pfbfile=features.pfbfile + local bitmap=features.bitmap + if not encfile then + return + end + local pfbfile=outfiles[tfmfile] + if pfbfile==nil then + if bitmap then + pfbfile=false + elseif type(pfbfile)~="string" then + pfbfile=tfmfile + end + if type(pfbfile)=="string" then + pfbfile=file.addsuffix(pfbfile,"pfb") + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile=false + end + outfiles[tfmfile]=pfbfile + end + local encoding=false + local vector=false + if type(pfbfile)=="string" then + local pfb=constructors.handlers.pfb + if pfb and pfb.loadvector then + local v,e=pfb.loadvector(pfbfile) + if v then + vector=v + end + if e then + encoding=e + end + end + end + if type(encfile)=="string" and encfile~="auto" then + encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding=encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid=tfmcache[tfmdata] + local tfmdata=table.copy(tfmdata) + local characters={} + local originals=tfmdata.characters + local indices={} + local parentfont={ "font",1 } + local private=tfmdata.privateoffset or constructors.privateoffset + local reported=encdone[tfmfile][encfile] + local backmap=vector and table.swapped(vector) + local done={} + for index,name in sortedhash(encoding) do + local unicode=unicoding[name] + local original=originals[index] + if original then + if unicode then + original.unicode=unicode + else + unicode=private + private=private+1 + if not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end + end + characters[unicode]=original + indices[index]=unicode + original.name=name + if backmap then + original.index=backmap[name] + else + original.commands={ parentfont,charcommand[index] } + original.oindex=index + end + done[name]=true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) + end + end + encdone[tfmfile][encfile]=true + for k,v in next,characters do + local kerns=v.kerns + if kerns then + local t={} + for k,v in next,kerns do + local i=indices[k] + if i then + t[i]=v + end + end + v.kerns=next(t) and t or nil + end + local ligatures=v.ligatures + if ligatures then + local t={} + for k,v in next,ligatures do + local i=indices[k] + if i then + t[i]=v + v.char=indices[v.char] + end + end + v.ligatures=next(t) and t or nil + end + end + tfmdata.fonts={ { id=virtualid } } + tfmdata.characters=characters + tfmdata.fullname=tfmdata.fullname or tfmdata.name + tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename=pfbfile + tfmdata.encodingbytes=2 + tfmdata.format="type1" + tfmdata.tounicode=1 + tfmdata.embedding="subset" + tfmdata.usedbitmap=bitmap and virtualid + tfmdata.private=private + return tfmdata + end +end +do + local template=[[ +/CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def + /CMapName /TeX-bitmap-%s def + /CMapType 2 def + 1 begincodespacerange + <00> + endcodespacerange + %s beginbfchar +%s + endbfchar + endcmap +CMapName currentdict /CMap defineresource pop end +end +end +]] + local flushstreamobject=lpdf and lpdf.flushstreamobject + local setfontattributes=lpdf and lpdf.setfontattributes + if not flushstreamobject then + flushstreamobject=function(data) + return pdf.obj { immediate=true,type="stream",string=data } + end + end + if not setfontattributes then + setfontattributes=function(id,data) + return pdf.setfontattributes(id,data) + end + end + function tfm.addtounicode(tfmdata) + local id=tfmdata.usedbitmap + local map={} + local char={} + for k,v in next,tfmdata.characters do + local index=v.oindex + local tounicode=v.tounicode + if index and tounicode then + map[index]=tounicode + end + end + for k,v in sortedhash(map) do + char[#char+1]=format("<%02X> <%s>",k,v) + end + char=concat(char,"\n") + local stream=format(template,id,id,#char,char) + local reference=flushstreamobject(stream,nil,true) + setfontattributes(id,format("/ToUnicode %i 0 R",reference)) + end +end +do + local everywhere={ ["*"]={ ["*"]=true } } + local noflags={ false,false,false,false } + local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local characters=data.characters + for u,c in next,characters do + local l=c.ligatures + local k=c.kerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v.char } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + end + for u,l in next,ligatures do + for k,v in next,l do + local vl=v.ligature + local dl=ligatures[vl] + if dl then + for kk,vv in next,dl do + v[kk]=vv + end + end + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences + data.shared.resources=data.shared.resources or resources + end + registertfmenhancer("normalize features",enhance_normalize_features) + registertfmenhancer("check extra features",otfenhancers.enhance) +end +registertfmfeature { + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } +} +registertfmfeature { + name="features", + description="features", + default=true, + initializers={ + base=otf.basemodeinitializer, + node=otf.nodemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] --- + +if not modules then modules={} end modules ['font-lua']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local report_lua=logs.reporter("fonts","lua loading") +local fonts=fonts +local readers=fonts.readers +fonts.formats.lua="lua" +local function check_lua(specification,fullname) + local fullname=resolvers.findfile(fullname) or "" + if fullname~="" then + local loader=loadfile(fullname) + loader=loader and loader() + return loader and loader(specification) + end +end +readers.check_lua=check_lua +function readers.lua(specification) + local original=specification.specification + if trace_defining then + report_lua("using lua reader for %a",original) + end + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name + end + end + return check_lua(specification,fullname) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] --- + +if not modules then modules={} end modules ['font-def']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lower,gsub=string.lower,string.gsub +local tostring,next=tostring,next +local lpegmatch=lpeg.match +local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basename +local formatters=string.formatters +local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys +local allocate=utilities.storage.allocate +local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) +local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) +trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading") +local report_defining=logs.reporter("fonts","defining") +local fonts=fonts +local fontdata=fonts.hashes.identifiers +local readers=fonts.readers +local definers=fonts.definers +local specifiers=fonts.specifiers +local constructors=fonts.constructors +local fontgoodies=fonts.goodies +readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' } +local variants=allocate() +specifiers.variants=variants +definers.methods=definers.methods or {} +local internalized=allocate() +local loadedfonts=constructors.loadedfonts +local designsizes=constructors.designsizes +local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end +local function makespecification(specification,lookup,name,sub,method,detail,size) + size=size or 655360 + if not lookup or lookup=="" then + lookup=definers.defaultlookup + end + if trace_defining then + report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", + specification,lookup,name,sub,method,detail) + end + local t={ + lookup=lookup, + specification=specification, + size=size, + name=name, + sub=sub, + method=method, + detail=detail, + resolved="", + forced="", + features={}, + } + return t +end +definers.makespecification=makespecification +if context then + local splitter,splitspecifiers=nil,"" + local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs + local left=P("(") + local right=P(")") + local colon=P(":") + local space=P(" ") + local lbrace=P("{") + local rbrace=P("}") + definers.defaultlookup="file" + local prefixpattern=P(false) + local function addspecifier(symbol) + splitspecifiers=splitspecifiers..symbol + local method=S(splitspecifiers) + local lookup=C(prefixpattern)*colon + local sub=left*C(P(1-left-right-method)^1)*right + local specification=C(method)*C(P(1)^1) + local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1) + splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc(""))) + end + local function addlookup(str) + prefixpattern=prefixpattern+P(str) + end + definers.addlookup=addlookup + addlookup("file") + addlookup("name") + addlookup("spec") + local function getspecification(str) + return lpegmatch(splitter,str or "") + end + definers.getspecification=getspecification + function definers.registersplit(symbol,action,verbosename) + addspecifier(symbol) + variants[symbol]=action + if verbosename then + variants[verbosename]=action + end + end + function definers.analyze(specification,size) + local lookup,name,sub,method,detail=getspecification(specification or "") + return makespecification(specification,lookup,name,sub,method,detail,size) + end +end +definers.resolvers=definers.resolvers or {} +local resolvers=definers.resolvers +function resolvers.file(specification) + local name=resolvefile(specification.name) + local suffix=lower(suffixonly(name)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=name + specification.name=removesuffix(name) + else + specification.name=name + end +end +function resolvers.name(specification) + local resolve=fonts.names.resolve + if resolve then + local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + if instance then + specification.instance=instance + local features=specification.features + if not features then + features={} + specification.features=features + end + local normal=features.normal + if not normal then + normal={} + features.normal=normal + end + normal.instance=instance + end + local suffix=lower(suffixonly(resolved)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=resolved + specification.name=removesuffix(resolved) + else + specification.name=resolved + end + end + else + resolvers.file(specification) + end +end +function resolvers.spec(specification) + local resolvespec=fonts.names.resolvespec + if resolvespec then + local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + specification.forced=lower(suffixonly(resolved)) + specification.forcedname=resolved + specification.name=removesuffix(resolved) + end + else + resolvers.name(specification) + end +end +function definers.resolve(specification) + if not specification.resolved or specification.resolved=="" then + local r=resolvers[specification.lookup] + if r then + r(specification) + end + end + if specification.forced=="" then + specification.forced=nil + specification.forcedname=nil + end + specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) + if specification.sub and specification.sub~="" then + specification.hash=specification.sub..' @ '..specification.hash + end + return specification +end +function definers.applypostprocessors(tfmdata) + local postprocessors=tfmdata.postprocessors + if postprocessors then + local properties=tfmdata.properties + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=gsub(lower(extrahash),"[^a-z]","-") + properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) + end + end + end + return tfmdata +end +local function checkembedding(tfmdata) + local properties=tfmdata.properties + local embedding + if directive_embedall then + embedding="full" + elseif properties and properties.filename and constructors.dontembed[properties.filename] then + embedding="no" + else + embedding="subset" + end + if properties then + properties.embedding=embedding + else + tfmdata.properties={ embedding=embedding } + end + tfmdata.embedding=embedding +end +local function checkfeatures(tfmdata) + local resources=tfmdata.resources + local shared=tfmdata.shared + if resources and shared then + local features=resources.features + local usedfeatures=shared.features + if features and usedfeatures then + local usedlanguage=usedfeatures.language or "dflt" + local usedscript=usedfeatures.script or "dflt" + local function check(what) + if what then + local foundlanguages={} + for feature,scripts in next,what do + if usedscript=="auto" or scripts["*"] then + elseif not scripts[usedscript] then + else + for script,languages in next,scripts do + if languages["*"] then + elseif context and not languages[usedlanguage] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,usedlanguage) + end + end + end + for script,languages in next,scripts do + for language in next,languages do + foundlanguages[language]=true + end + end + end + if false then + foundlanguages["*"]=nil + foundlanguages=sortedkeys(foundlanguages) + for feature,scripts in sortedhash(what) do + for script,languages in next,scripts do + if not languages["*"] then + for i=1,#foundlanguages do + local language=foundlanguages[i] + if context and not languages[language] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,language) + end + end + end + end + end + end + end + end + check(features.gsub) + check(features.gpos) + end + end +end +function definers.loadfont(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=loadedfonts[hash] + if not tfmdata then + local forced=specification.forced or "" + if forced~="" then + local reader=readers[lower(forced)] + tfmdata=reader and reader(specification) + if not tfmdata then + report_defining("forced type %a of %a not found",forced,specification.name) + end + else + local sequence=readers.sequence + for s=1,#sequence do + local reader=sequence[s] + if readers[reader] then + if trace_defining then + report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) + end + tfmdata=readers[reader](specification) + if tfmdata then + break + else + specification.filename=nil + end + end + end + end + if tfmdata then + tfmdata=definers.applypostprocessors(tfmdata) + checkembedding(tfmdata) + loadedfonts[hash]=tfmdata + designsizes[specification.hash]=tfmdata.parameters.designsize + checkfeatures(tfmdata) + end + end + if not tfmdata then + report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) + end + return tfmdata +end +function constructors.readanddefine(name,size) + local specification=definers.analyze(name,size) + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local id=definers.registered(hash) + if not id then + local tfmdata=definers.loadfont(specification) + if tfmdata then + tfmdata.properties.hash=hash + id=font.define(tfmdata) + definers.register(tfmdata,id) + else + id=0 + end + end + return fontdata[id],id +end +function definers.registered(hash) + local id=internalized[hash] + return id,id and fontdata[id] +end +function definers.register(tfmdata,id) + if tfmdata and id then + local hash=tfmdata.properties.hash + if not hash then + report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") + elseif not internalized[hash] then + internalized[hash]=id + if trace_defining then + report_defining("registering font, id %s, hash %a",id,hash) + end + fontdata[id]=tfmdata + end + end +end +function definers.read(specification,size,id) + statistics.starttiming(fonts) + if type(specification)=="string" then + specification=definers.analyze(specification,size) + end + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=definers.registered(hash) + if tfmdata then + if trace_defining then + report_defining("already hashed: %s",hash) + end + else + tfmdata=definers.loadfont(specification) + if tfmdata then + tfmdata.original=specification.specification + if trace_defining then + report_defining("loaded and hashed: %s",hash) + end + tfmdata.properties.hash=hash + if id then + definers.register(tfmdata,id) + end + else + if trace_defining then + report_defining("not loaded and hashed: %s",hash) + end + end + end + if not tfmdata then + report_defining("unknown font %a, loading aborted",specification.name) + elseif trace_defining and type(tfmdata)=="table" then + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", + properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, + properties.encodingname,properties.fullname,basename(properties.filename)) + end + statistics.stoptiming(fonts) + return tfmdata +end +function font.getfont(id) + return fontdata[id] +end +if not context then + callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp” 5ff497c993112d4fef4c148348d964eb] --- + +if not modules then modules={} end modules ['font-shp']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local tonumber,next=tonumber,next +local concat=table.concat +local formatters,lower=string.formatters,string.lower +local otf=fonts.handlers.otf +local afm=fonts.handlers.afm +local pfb=fonts.handlers.pfb +local hashes=fonts.hashes +local identifiers=hashes.identifiers +local version=0.009 +local shapescache=containers.define("fonts","shapes",version,true) +local streamscache=containers.define("fonts","streams",version,true) +local compact_streams=false +directives.register("fonts.streams.compact",function(v) compact_streams=v end) +local function packoutlines(data,makesequence) + local subfonts=data.subfonts + if subfonts then + for i=1,#subfonts do + packoutlines(subfonts[i],makesequence) + end + return + end + local common=data.segments + if common then + return + end + local glyphs=data.glyphs + if not glyphs then + return + end + if makesequence then + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + local sequence={} + local nofsequence=0 + for i=1,#segments do + local segment=segments[i] + local nofsegment=#segment + nofsequence=nofsequence+1 + sequence[nofsequence]=segment[nofsegment] + for i=1,nofsegment-1 do + nofsequence=nofsequence+1 + sequence[nofsequence]=segment[i] + end + end + glyph.sequence=sequence + glyph.segments=nil + end + end + end + else + local hash={} + local common={} + local reverse={} + local last=0 + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local h=concat(segments[i]," ") + hash[h]=(hash[h] or 0)+1 + end + end + end + end + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local segment=segments[i] + local h=concat(segment," ") + if hash[h]>1 then + local idx=reverse[h] + if not idx then + last=last+1 + reverse[h]=last + common[last]=segment + idx=last + end + segments[i]=idx + end + end + end + end + end + if last>0 then + data.segments=common + end + end +end +local function unpackoutlines(data) + local subfonts=data.subfonts + if subfonts then + for i=1,#subfonts do + unpackoutlines(subfonts[i]) + end + return + end + local common=data.segments + if not common then + return + end + local glyphs=data.glyphs + if not glyphs then + return + end + for index=0,#glyphs do + local glyph=glyphs[index] + if glyph then + local segments=glyph.segments + if segments then + for i=1,#segments do + local c=common[segments[i]] + if c then + segments[i]=c + end + end + end + end + end + data.segments=nil +end +local readers=otf.readers +local cleanname=otf.readers.helpers.cleanname +local function makehash(filename,sub,instance) + local name=cleanname(file.basename(filename)) + if instance then + return formatters["%s-%s-%s"](name,sub or 0,cleanname(instance)) + else + return formatters["%s-%s"] (name,sub or 0) + end +end +local function loadoutlines(cache,filename,sub,instance) + local base=file.basename(filename) + local name=file.removesuffix(base) + local kind=file.suffix(filename) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local sub=tonumber(sub) + if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=otf.readers.loadshapes(filename,sub,instance) + if data then + data.size=size + data.format=data.format or (kind=="otf" and "opentype") or "truetype" + data.time=time + packoutlines(data) + containers.write(cache,hash,data) + data=containers.read(cache,hash) + end + end + unpackoutlines(data) + elseif size>0 and (kind=="pfb") then + local hash=containers.cleanname(base) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=afm.readers.loadshapes(filename) + if data then + data.size=size + data.format="type1" + data.time=time + packoutlines(data) + containers.write(cache,hash,data) + data=containers.read(cache,hash) + end + end + unpackoutlines(data) + else + data={ + filename=filename, + size=0, + time=time, + format="unknown", + units=1000, + glyphs={} + } + end + return data +end +local function cachethem(cache,hash,data) + containers.write(cache,hash,data,compact_streams) + return containers.read(cache,hash) +end +local function loadstreams(cache,filename,sub,instance) + local base=file.basename(filename) + local name=file.removesuffix(base) + local kind=lower(file.suffix(filename)) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local sub=tonumber(sub) + if size>0 and (kind=="otf" or kind=="ttf" or kind=="ttc") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + data=otf.readers.loadshapes(filename,sub,instance,true) + if data then + local glyphs=data.glyphs + local streams={} + if glyphs then + for i=0,#glyphs do + local glyph=glyphs[i] + if glyph then + streams[i]=glyph.stream or "" + else + streams[i]="" + end + end + end + data.streams=streams + data.glyphs=nil + data.size=size + data.format=data.format or (kind=="otf" and "opentype") or "truetype" + data.time=time + data=cachethem(cache,hash,data) + end + end + elseif size>0 and (kind=="pfb") then + local hash=makehash(filename,sub,instance) + data=containers.read(cache,hash) + if not data or data.time~=time or data.size~=size then + local names,encoding,streams,metadata=pfb.loadvector(filename,false,true) + if streams then + local fontbbox=metadata.fontbbox or { 0,0,0,0 } + for i=0,#streams do + streams[i]=streams[i].stream or "\14" + end + data={ + filename=filename, + size=size, + time=time, + format="type1", + streams=streams, + fontheader={ + fontversion=metadata.version, + units=1000, + xmin=fontbbox[1], + ymin=fontbbox[2], + xmax=fontbbox[3], + ymax=fontbbox[4], + }, + horizontalheader={ + ascender=0, + descender=0, + }, + maximumprofile={ + nofglyphs=#streams+1, + }, + names={ + copyright=metadata.copyright, + family=metadata.familyname, + fullname=metadata.fullname, + fontname=metadata.fontname, + subfamily=metadata.subfamilyname, + trademark=metadata.trademark, + notice=metadata.notice, + version=metadata.version, + }, + cffinfo={ + familyname=metadata.familyname, + fullname=metadata.fullname, + italicangle=metadata.italicangle, + monospaced=metadata.isfixedpitch and true or false, + underlineposition=metadata.underlineposition, + underlinethickness=metadata.underlinethickness, + weight=metadata.weight, + }, + } + data=cachethem(cache,hash,data) + end + end + else + data={ + filename=filename, + size=0, + time=time, + format="unknown", + streams={} + } + end + return data +end +local loadedshapes={} +local loadedstreams={} +local function loadoutlinedata(fontdata,streams) + local properties=fontdata.properties + local filename=properties.filename + local subindex=fontdata.subindex + local instance=properties.instance + local hash=makehash(filename,subindex,instance) + local loaded=loadedshapes[hash] + if not loaded then + loaded=loadoutlines(shapescache,filename,subindex,instance) + loadedshapes[hash]=loaded + end + return loaded +end +hashes.shapes=table.setmetatableindex(function(t,k) + local f=identifiers[k] + if f then + return loadoutlinedata(f) + end +end) +local function getstreamhash(fontid) + local fontdata=identifiers[fontid] + if fontdata then + local properties=fontdata.properties + return makehash(properties.filename,properties.subfont,properties.instance) + end +end +local function loadstreamdata(fontdata) + local properties=fontdata.properties + local shared=fontdata.shared + local rawdata=shared and shared.rawdata + local metadata=rawdata and rawdata.metadata + local filename=properties.filename + local subindex=metadata and metadata.subfontindex + local instance=properties.instance + local hash=makehash(filename,subindex,instance) + local loaded=loadedstreams[hash] + if not loaded then + loaded=loadstreams(streamscache,filename,subindex,instance) + loadedstreams[hash]=loaded + end + return loaded +end +hashes.streams=table.setmetatableindex(function(t,k) + local f=identifiers[k] + if f then + return loadstreamdata(f) + end +end) +otf.loadoutlinedata=loadoutlinedata +otf.loadstreamdata=loadstreamdata +otf.loadshapes=loadshapes +otf.getstreamhash=getstreamhash +local streams=fonts.hashes.streams +callback.register("glyph_stream_provider",function(id,index,mode) + if id>0 then + local streams=streams[id].streams + if streams then + return streams[index] or "" + end + end + return "" +end) + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] --- + +if not modules then modules={} end modules ['luatex-fonts-def']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local fonts=fonts +fonts.constructors.namemode="specification" +function fonts.definers.getspecification(str) + return "",str,"",":",str +end +local list={} +local function issome () list.lookup='name' end +local function isfile () list.lookup='file' end +local function isname () list.lookup='name' end +local function thename(s) list.name=s end +local function issub (v) list.sub=v end +local function iscrap (s) list.crap=string.lower(s) end +local function iskey (k,v) list[k]=v end +local function istrue (s) list[s]=true end +local function isfalse(s) list[s]=false end +local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs +local spaces=P(" ")^0 +local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0) +local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces +local filename_1=P("file:")/isfile*(namespec/thename) +local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]") +local fontname_1=P("name:")/isname*(namespec/thename) +local fontname_2=P(true)/issome*(namespec/thename) +local sometext=R("az","AZ","09")^1 +local somekey=R("az","AZ","09")^1 +local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1 +local truevalue=P("+")*spaces*(sometext/istrue) +local falsevalue=P("-")*spaces*(sometext/isfalse) +local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey +local somevalue=sometext/istrue +local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")") +local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces +local options=P(":")*spaces*(P(";")^0*option)^0 +local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0 +function fonts.definers.analyze(str,size) + local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) + list={} + lpeg.match(pattern,str) + list.crap=nil + if list.name then + specification.name=list.name + list.name=nil + end + if list.lookup then + specification.lookup=list.lookup + list.lookup=nil + end + if list.sub then + specification.sub=list.sub + list.sub=nil + end + specification.features.normal=fonts.handlers.otf.features.normalize(list) + list=nil + return specification +end +function fonts.definers.applypostprocessors(tfmdata) + local postprocessors=tfmdata.postprocessors + if postprocessors then + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=string.gsub(lower(extrahash),"[^a-z]","-") + tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) + end + end + end + return tfmdata +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] --- + +if not modules then modules={} end modules ['luatex-fonts-ext']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local byte=string.byte +local fonts=fonts +local handlers=fonts.handlers +local otf=handlers.otf +local afm=handlers.afm +local registerotffeature=otf.features.register +local registerafmfeature=afm.features.register +function fonts.loggers.onetimemessage() end +fonts.protrusions=fonts.protrusions or {} +fonts.protrusions.setups=fonts.protrusions.setups or {} +local setups=fonts.protrusions.setups +setups['default']={ + factor=1, + left=1, + right=1, + [0x002C]={ 0,1 }, + [0x002E]={ 0,1 }, + [0x003A]={ 0,1 }, + [0x003B]={ 0,1 }, + [0x002D]={ 0,1 }, + [0x2013]={ 0,0.50 }, + [0x2014]={ 0,0.33 }, + [0x3001]={ 0,1 }, + [0x3002]={ 0,1 }, + [0x060C]={ 0,1 }, + [0x061B]={ 0,1 }, + [0x06D4]={ 0,1 }, +} +local function initializeprotrusion(tfmdata,value) + if value then + local setup=setups[value] + if setup then + local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 + local emwidth=tfmdata.parameters.quad + tfmdata.parameters.protrusion={ + auto=true, + } + for i,chr in next,tfmdata.characters do + local v,pl,pr=setup[i],nil,nil + if v then + pl,pr=v[1],v[2] + end + if pl and pl~=0 then chr.left_protruding=left*pl*factor end + if pr and pr~=0 then chr.right_protruding=right*pr*factor end + end + end + end +end +local specification={ + name="protrusion", + description="shift characters into the left and or right margin", + initializers={ + base=initializeprotrusion, + node=initializeprotrusion, + } +} +registerotffeature(specification) +registerafmfeature(specification) +fonts.expansions=fonts.expansions or {} +fonts.expansions.setups=fonts.expansions.setups or {} +local setups=fonts.expansions.setups +setups['default']={ + stretch=2, + shrink=2, + step=.5, + factor=1, + [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, + [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, + [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, + [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, + [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, + [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, + [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, + [byte('w')]=0.7,[byte('z')]=0.7, + [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, +} +local function initializeexpansion(tfmdata,value) + if value then + local setup=setups[value] + if setup then + local factor=setup.factor or 1 + tfmdata.parameters.expansion={ + stretch=10*(setup.stretch or 0), + shrink=10*(setup.shrink or 0), + step=10*(setup.step or 0), + auto=true, + } + for i,chr in next,tfmdata.characters do + local v=setup[i] + if v and v~=0 then + chr.expansion_factor=v*factor + else + chr.expansion_factor=factor + end + end + end + end +end +local specification={ + name="expansion", + description="apply hz optimization", + initializers={ + base=initializeexpansion, + node=initializeexpansion, + } +} +registerotffeature(specification) +registerafmfeature(specification) +if not otf.features.normalize then + otf.features.normalize=function(t) + if t.rand then + t.rand="random" + end + return t + end +end +function fonts.helpers.nametoslot(name) + local t=type(name) + if t=="string" then + local tfmdata=fonts.hashes.identifiers[currentfont()] + local shared=tfmdata and tfmdata.shared + local fntdata=shared and shared.rawdata + return fntdata and fntdata.resources.unicodes[name] + elseif t=="number" then + return n + end +end +fonts.encodings=fonts.encodings or {} +local reencodings={} +fonts.encodings.reencodings=reencodings +local function specialreencode(tfmdata,value) + local encoding=value and reencodings[value] + if encoding then + local temp={} + local char=tfmdata.characters + for k,v in next,encoding do + temp[k]=char[v] + end + for k,v in next,temp do + char[k]=temp[k] + end + return string.format("reencoded:%s",value) + end +end +local function initialize(tfmdata,value) + tfmdata.postprocessors=tfmdata.postprocessors or {} + table.insert(tfmdata.postprocessors, + function(tfmdata) + return specialreencode(tfmdata,value) + end + ) +end +registerotffeature { + name="reencode", + description="reencode characters", + manipulators={ + base=initialize, + node=initialize, + } +} +local function initialize(tfmdata,key,value) + if value then + tfmdata.mathparameters=nil + end +end +registerotffeature { + name="ignoremathconstants", + description="ignore math constants table", + initializers={ + base=initialize, + node=initialize, + } +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] --- + +if not modules then modules={} end modules ['font-imp-tex']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local specification={ + type="ligature", + order={ "tlig" }, + prepend=true, + data={ + [0x2013]={ 0x002D,0x002D }, + [0x2014]={ 0x002D,0x002D,0x002D }, + }, +} +addotffeature("tlig",specification) +registerotffeature { + name="tlig", + description="tex ligatures", +} +local specification={ + type="substitution", + order={ "trep" }, + prepend=true, + data={ + [0x0027]=0x2019, + }, +} +addotffeature("trep",specification) +registerotffeature { + name="trep", + description="tex replacements", +} +local anum_arabic={ + [0x0030]=0x0660, + [0x0031]=0x0661, + [0x0032]=0x0662, + [0x0033]=0x0663, + [0x0034]=0x0664, + [0x0035]=0x0665, + [0x0036]=0x0666, + [0x0037]=0x0667, + [0x0038]=0x0668, + [0x0039]=0x0669, +} +local anum_persian={ + [0x0030]=0x06F0, + [0x0031]=0x06F1, + [0x0032]=0x06F2, + [0x0033]=0x06F3, + [0x0034]=0x06F4, + [0x0035]=0x06F5, + [0x0036]=0x06F6, + [0x0037]=0x06F7, + [0x0038]=0x06F8, + [0x0039]=0x06F9, +} +local function valid(data) + local features=data.resources.features + if features then + for k,v in next,features do + for k,v in next,v do + if v.arab then + return true + end + end + end + end +end +local specification={ + { + type="substitution", + features={ arab={ urd=true,dflt=true } }, + order={ "anum" }, + data=anum_arabic, + valid=valid, + }, + { + type="substitution", + features={ arab={ urd=true } }, + order={ "anum" }, + data=anum_persian, + valid=valid, + }, +} +addotffeature("anum",specification) +registerotffeature { + name="anum", + description="arabic digits", +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] --- + +if not modules then modules={} end modules ['font-imp-ligatures']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lpegmatch=lpeg.match +local utfsplit=utf.split +local settings_to_array=utilities.parsers.settings_to_array +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local lookups={} +local protect={} +local revert={} +local zwjchar=0x200C +local zwj={ zwjchar } +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + prepend=true, + future=true, + lookups={ + { + type="multiple", + data=lookups, + }, + }, + data={ + rules=protect, + } +} +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + append=true, + overload=false, + lookups={ + { + type="ligature", + data=lookups, + }, + }, + data={ + rules=revert, + } +} +registerotffeature { + name='blockligatures', + description='block certain ligatures', +} +local splitter=lpeg.splitat(":") +local function blockligatures(str) + local t=settings_to_array(str) + for i=1,#t do + local ti=t[i] + local before,current,after=lpegmatch(splitter,ti) + if current and after then + if before then + before=utfsplit(before) + for i=1,#before do + before[i]={ before[i] } + end + end + if current then + current=utfsplit(current) + end + if after then + after=utfsplit(after) + for i=1,#after do + after[i]={ after[i] } + end + end + else + before=nil + current=utfsplit(ti) + after=nil + end + if #current>1 then + local one=current[1] + local two=current[2] + lookups[one]={ one,zwjchar } + local one={ one } + local two={ two } + local new=#protect+1 + protect[new]={ + before=before, + current={ one,two }, + after=after, + lookups={ 1 }, + } + revert[new]={ + current={ one,zwj }, + after={ two }, + lookups={ 1 }, + } + end + end +end +otf.helpers.blockligatures=blockligatures +if context then + interfaces.implement { + name="blockligatures", + arguments="string", + actions=blockligatures, + } +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics” ae563638fa29a4ff3e8e4d1e81fd35ae] --- + +if not modules then modules={} end modules ['font-imp-italics']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local function initialize(tfmdata,key,value) + for unicode,character in next,tfmdata.characters do + local olditalic=character.italic + if olditalic and olditalic~=0 then + character.width=character.width+olditalic + character.italic=0 + end + end +end +local specification={ + name="italicwidths", + description="add italic to width", + manipulators={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initialize(tfmdata,value) + if value then + local parameters=tfmdata.parameters + local italicangle=parameters.italicangle + if italicangle and italicangle~=0 then + local properties=tfmdata.properties + local factor=tonumber(value) or 1 + properties.hasitalics=true + properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 + end + end +end +local specification={ + name="itlc", + description="italic correction", + initializers={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +if context then + local function initialize(tfmdata,value) + tfmdata.properties.textitalics=toboolean(value) + end + local specification={ + name="textitalics", + description="use alternative text italic correction", + initializers={ + base=initialize, + node=initialize, + } + } + registerotffeature(specification) + registerafmfeature(specification) + local letter=characters.is_letter + local always=true + local function collapseitalics(tfmdata,key,value) + local threshold=value==true and 100 or tonumber(value) + if threshold and threshold>0 then + if threshold>100 then + threshold=100 + end + for unicode,data in next,tfmdata.characters do + if always or letter[unicode] or letter[data.unicode] then + local italic=data.italic + if italic and italic~=0 then + local width=data.width + if width and width~=0 then + local delta=threshold*italic/100 + data.width=width+delta + data.italic=italic-delta + end + end + end + end + end + end + local dimensions_specification={ + name="collapseitalics", + description="collapse italics", + manipulators={ + base=collapseitalics, + node=collapseitalics, + } + } + registerotffeature(dimensions_specification) + registerafmfeature(dimensions_specification) +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects” a2dde5e071fcb3fc7b90f2bcd5aa4f22] --- + +if not modules then modules={} end modules ['font-imp-effects']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber=next,type,tonumber +local is_boolean=string.is_boolean +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too +local helpers=fonts.helpers +local prependcommands=helpers.prependcommands +local charcommand=helpers.commands.char +local leftcommand=helpers.commands.left +local rightcommand=helpers.commands.right +local upcommand=helpers.commands.up +local downcommand=helpers.commands.down +local dummycommand=helpers.commands.dummy +local report_effect=logs.reporter("fonts","effect") +local report_slant=logs.reporter("fonts","slant") +local report_extend=logs.reporter("fonts","extend") +local report_squeeze=logs.reporter("fonts","squeeze") +local trace=false +trackers.register("fonts.effect",function(v) trace=v end) +trackers.register("fonts.slant",function(v) trace=v end) +trackers.register("fonts.extend",function(v) trace=v end) +trackers.register("fonts.squeeze",function(v) trace=v end) +local function initializeslant(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>1 then + value=1 + elseif value<-1 then + value=-1 + end + if trace then + report_slant("applying %0.3f",value) + end + tfmdata.parameters.slantfactor=value +end +local specification={ + name="slant", + description="slant glyphs", + initializers={ + base=initializeslant, + node=initializeslant, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeextend(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_extend("applying %0.3f",value) + end + tfmdata.parameters.extendfactor=value +end +local specification={ + name="extend", + description="scale glyphs horizontally", + initializers={ + base=initializeextend, + node=initializeextend, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializesqueeze(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_squeeze("applying %0.3f",value) + end + tfmdata.parameters.squeezefactor=value +end +local specification={ + name="squeeze", + description="scale glyphs vertically", + initializers={ + base=initializesqueeze, + node=initializesqueeze, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local effects={ + inner=0, + normal=0, + outer=1, + outline=1, + both=2, + hidden=3, +} +local function initializeeffect(tfmdata,value) + local spec + if type(value)=="number" then + spec={ width=value } + else + spec=settings_to_hash(value) + end + local effect=spec.effect or "both" + local width=tonumber(spec.width) or 0 + local mode=effects[effect] + if not mode then + report_effect("invalid effect %a",effect) + elseif width==0 and mode==0 then + report_effect("invalid width %a for effect %a",width,effect) + else + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=mode + parameters.width=width*1000 + if is_boolean(spec.auto)==true then + local squeeze=1-width/20 + local average=(1-squeeze)*width*100 + spec.squeeze=squeeze + spec.extend=1+width/2 + spec.wdelta=average + spec.hdelta=average/2 + spec.ddelta=average/2 + spec.vshift=average/2 + end + local factor=tonumber(spec.factor) or 0 + local hfactor=tonumber(spec.hfactor) or factor + local vfactor=tonumber(spec.vfactor) or factor + local delta=tonumber(spec.delta) or 1 + local wdelta=tonumber(spec.wdelta) or delta + local hdelta=tonumber(spec.hdelta) or delta + local ddelta=tonumber(spec.ddelta) or hdelta + local vshift=tonumber(spec.vshift) or 0 + local slant=spec.slant + local extend=spec.extend + local squeeze=spec.squeeze + if slant then + initializeslant(tfmdata,slant) + end + if extend then + initializeextend(tfmdata,extend) + end + if squeeze then + initializesqueeze(tfmdata,squeeze) + end + properties.effect={ + effect=effect, + width=width, + factor=factor, + hfactor=hfactor, + vfactor=vfactor, + wdelta=wdelta, + hdelta=hdelta, + ddelta=ddelta, + vshift=vshift, + slant=tfmdata.parameters.slantfactor, + extend=tfmdata.parameters.extendfactor, + squeeze=tfmdata.parameters.squeezefactor, + } + end +end +local rules={ + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", +} +local setmathparameters +local setmathcharacters +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end + end + end + end + setmathcharacters=function() + end +else + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end + end + end + end + setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next + wdpatch(char) + htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end + end + end + end + end +end +local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 +local function manipulateeffect(tfmdata) + local effect=tfmdata.properties.effect + if effect then + local characters=tfmdata.characters + local parameters=tfmdata.parameters + local mathparameters=tfmdata.mathparameters + local multiplier=effect.width*100 + local factor=parameters.factor + local hfactor=parameters.hfactor + local vfactor=parameters.vfactor + local wdelta=effect.wdelta*hfactor*multiplier + local hdelta=effect.hdelta*vfactor*multiplier + local ddelta=effect.ddelta*vfactor*multiplier + local vshift=effect.vshift*vfactor*multiplier + local squeeze=effect.squeeze + local hshift=wdelta/2 + local dx=multiplier*vfactor + local dy=vshift + local factor=(1+effect.factor)*factor + local hfactor=(1+effect.hfactor)*hfactor + local vfactor=(1+effect.vfactor)*vfactor + if shiftmode then + parameters.hshift=hshift + parameters.vshift=vshift + else + vshift=vshift~=0 and upcommand[vshift] or false + hshift=rightcommand[hshift] + end + for unicode,character in next,characters do + local oldwidth=character.width + local oldheight=character.height + local olddepth=character.depth + if oldwidth and oldwidth>0 then + character.width=oldwidth+wdelta + if not shiftmode then + local commands=character.commands + if vshift then + if commands then + prependcommands (commands, + hshift, + vshift + ) + else + character.commands={ + hshift, + vshift, + charcommand[unicode] + } + end + else + if commands then + prependcommands (commands, + hshift + ) + else + character.commands={ + hshift, + charcommand[unicode] + } + end + end + end + end + if oldheight and oldheight>0 then + character.height=oldheight+hdelta + end + if olddepth and olddepth>0 then + character.depth=olddepth+ddelta + end + end + if mathparameters then + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + end + parameters.factor=factor + parameters.hfactor=hfactor + parameters.vfactor=vfactor + if trace then + report_effect("applying") + report_effect(" effect : %s",effect.effect) + report_effect(" width : %s => %s",effect.width,multiplier) + report_effect(" factor : %s => %s",effect.factor,factor ) + report_effect(" hfactor : %s => %s",effect.hfactor,hfactor) + report_effect(" vfactor : %s => %s",effect.vfactor,vfactor) + report_effect(" wdelta : %s => %s",effect.wdelta,wdelta) + report_effect(" hdelta : %s => %s",effect.hdelta,hdelta) + report_effect(" ddelta : %s => %s",effect.ddelta,ddelta) + end + end +end +local specification={ + name="effect", + description="apply effects to glyphs", + initializers={ + base=initializeeffect, + node=initializeeffect, + }, + manipulators={ + base=manipulateeffect, + node=manipulateeffect, + }, +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeoutline(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + else + value=tonumber(value) or 0 + end + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=effects.outline + parameters.width=value*1000 + properties.effect={ + effect=effect, + width=width, + } +end +local specification={ + name="outline", + description="outline glyphs", + initializers={ + base=initializeoutline, + node=initializeoutline, + } +} +registerotffeature(specification) +registerafmfeature(specification) + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] --- + + +fonts.handlers.otf.addfeature { + ["dataset"]={ + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, + }, + }, + ["name"]="collapse", + ["prepend"]=true, + ["type"]="ligature", +} + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig”] --- + + +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn” 10ecdf01e7c926e5128ad8a9dff4d677] --- + +if not modules then modules={} end modules ['luatex-fonts-gbn']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +if context then + os.exit() +end +local next=next +local fonts=fonts +local nodes=nodes +local nuts=nodes.nuts +local traverse_id=nuts.traverse_id +local flush_node=nuts.flush_node +local glyph_code=nodes.nodecodes.glyph +local disc_code=nodes.nodecodes.disc +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfont=nuts.getfont +local getchar=nuts.getchar +local getid=nuts.getid +local getboth=nuts.getboth +local getprev=nuts.getprev +local getnext=nuts.getnext +local getdisc=nuts.getdisc +local setchar=nuts.setchar +local setlink=nuts.setlink +local setprev=nuts.setprev +local n_ligaturing=node.ligaturing +local n_kerning=node.kerning +local d_ligaturing=nuts.ligaturing +local d_kerning=nuts.kerning +local basemodepass=true +local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end +local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end +function node.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return n_ligaturing(...) +end +function node.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return n_kerning(...) +end +function nuts.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return d_ligaturing(...) +end +function nuts.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return d_kerning(...) +end +function nodes.handlers.setbasemodepass(v) + basemodepass=v +end +local function nodepass(head,groupcode,size,packtype,direction) + local fontdata=fonts.hashes.identifiers + if fontdata then + local usedfonts={} + local basefonts={} + local prevfont=nil + local basefont=nil + local variants=nil + local redundant=nil + local nofused=0 + for n in traverse_id(glyph_code,head) do + local font=getfont(n) + if font~=prevfont then + if basefont then + basefont[2]=getprev(n) + end + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + elseif basemodepass then + basefont={ n,nil } + basefonts[#basefonts+1]=basefont + end + end + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + else + local tfmdata=fontdata[prevfont] + if tfmdata then + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + end + end + if variants then + local char=getchar(n) + if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then + local hash=variants[char] + if hash then + local p=getprev(n) + if p and getid(p)==glyph_code then + local variant=hash[getchar(p)] + if variant then + setchar(p,variant) + end + end + end + if not redundant then + redundant={ n } + else + redundant[#redundant+1]=n + end + end + end + end + local nofbasefonts=#basefonts + if redundant then + for i=1,#redundant do + local r=redundant[i] + local p,n=getboth(r) + if r==head then + head=n + setprev(n) + else + setlink(p,n) + end + if nofbasefonts>0 then + for i=1,nofbasefonts do + local bi=basefonts[i] + if r==bi[1] then + bi[1]=n + end + if r==bi[2] then + bi[2]=n + end + end + end + flush_node(r) + end + end + for d in traverse_id(disc_code,head) do + local _,_,r=getdisc(d) + if r then + for n in traverse_id(glyph_code,r) do + local font=getfont(n) + if font~=prevfont then + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + end + end + end + end + end + end + end + end + if next(usedfonts) then + for font,processors in next,usedfonts do + for i=1,#processors do + head=processors[i](head,font,0,direction,nofused) or head + end + end + end + if basemodepass and nofbasefonts>0 then + for i=1,nofbasefonts do + local range=basefonts[i] + local start=range[1] + local stop=range[2] + if start then + local front=head==start + local prev,next + if stop then + next=getnext(stop) + start,stop=d_ligaturing(start,stop) + start,stop=d_kerning(start,stop) + else + prev=getprev(start) + start=d_ligaturing(start) + start=d_kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and head~=start then + head=start + end + end + end + end + end + return head +end +local function basepass(head) + if basemodepass then + head=d_ligaturing(head) + head=d_kerning(head) + end + return head +end +local protectpass=node.direct.protect_glyphs +local injectpass=nodes.injections.handler +function nodes.handlers.nodepass(head,...) + if head then + return tonode(nodepass(tonut(head),...)) + end +end +function nodes.handlers.basepass(head) + if head then + return tonode(basepass(tonut(head))) + end +end +function nodes.handlers.injectpass(head) + if head then + return tonode(injectpass(tonut(head))) + end +end +function nodes.handlers.protectpass(head) + if head then + protectpass(tonut(head)) + return head + end +end +function nodes.simple_font_handler(head,groupcode,size,packtype,direction) + if head then + head=tonut(head) + head=nodepass(head,groupcode,size,packtype,direction) + head=injectpass(head) + if not basemodepass then + head=basepass(head) + end + protectpass(head) + head=tonode(head) + end + return head +end + +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn”] --- + + +--- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua index 67abf707b1..25f5473a5a 100644 --- a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua +++ b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua @@ -107,6 +107,7 @@ nuts.getkern = direct.getkern nuts.getlist = direct.getlist nuts.getnext = direct.getnext nuts.getoffsets = direct.getoffsets +nuts.getoptions = direct.getoptions or function() return 0 end nuts.getprev = direct.getprev nuts.getsubtype = direct.getsubtype nuts.getwidth = direct.getwidth @@ -206,6 +207,19 @@ local copy_node = nuts.copy_node local glyph_code = nodes.nodecodes.glyph local ligature_code = nodes.glyphcodes.ligature +do -- this is consistent with the rest of context, not that we need it + + local p = nodecodes.localpar or nodecodes.local_par + + if p then + nodecodes.par = p + nodecodes[p] = "par" + nodecodes.localpar = p -- for old times sake + nodecodes.local_par = p -- for old times sake + end + +end + do local get_components = node.direct.getcomponents @@ -264,11 +278,16 @@ do return 0 end + local function flush_components() + -- this is a no-op in mkiv / generic + end + nuts.set_components = set_components nuts.get_components = get_components nuts.copy_only_glyphs = copy_only_glyphs nuts.copy_no_components = copy_no_components nuts.count_components = count_components + nuts.flush_components = flush_components end diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua index 0cff896e8d..91ee83b19b 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua @@ -823,7 +823,7 @@ end -- quite often 0, 1, 2 -function readarray(f,offset) +local function readarray(f,offset) if offset then setposition(f,offset) end diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua index bd6cce8795..43ce82b71a 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua @@ -215,62 +215,88 @@ local rules = { -- end -- end -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta ~= 0 then - for i=1,#rules do - local name = rules[i] - local value = mathparameters[name] - if value then - mathparameters[name] = (squeeze or 1) * (value + dx) +-- radicals are not yet ok + +local setmathparameters +local setmathcharacters + +if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then + + setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dy) + end end end end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + setmathcharacters = function() + end - local function wdpatch(char) - if wsnap ~= 0 then - char.width = char.width + wdelta/2 +else + + setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dy) + end + end end end - local function htpatch(char) - if hsnap ~= 0 then - local height = char.height - if height then - char.height = char.height + 2 * dy + setmathcharacters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + + -- still not the perfect rule + + local function wdpatch(char) + if wsnap ~= 0 then + char.width = char.width + wdelta/2 + end + end + + local function htpatch(char) + if hsnap ~= 0 then + local height = char.height + if height then + char.height = char.height + 2 * dy + end end end - end - local character = characters[0x221A] + local character = characters[0x221A] - if character and character.next then --- print("base char",0x221A,table.sequenced(character)) - local char = character - local next = character.next - wdpatch(char) - htpatch(char) - while next do - char = characters[next] + if character and character.next then + local char = character + local next = character.next wdpatch(char) htpatch(char) --- print("next char",next,table.sequenced(char)) - next = char.next - end - if char then - local v = char.vert_variants - if v then - local top = v[#v] - if top then - local char = characters[top.glyph] --- print("top char",top.glyph,table.sequenced(char)) - htpatch(char) + while next do + char = characters[next] + wdpatch(char) + htpatch(char) + next = char.next + end + if char then + local v = char.vert_variants + if v then + local top = v[#v] + if top then + local char = characters[top.glyph] + htpatch(char) + end end end end + end + end -- local show_effect = { "lua", function(f,c) @@ -278,10 +304,7 @@ end -- inspect(fonts.hashes.characters[f][c]) -- end } --- local show_effect = { "lua", "print('!')" } - ------ shiftmode = false -- test in mkiv and lmtx -local shiftmode = CONTEXTLMTXMODE > 0 +local shiftmode = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 local function manipulateeffect(tfmdata) local effect = tfmdata.properties.effect @@ -358,7 +381,7 @@ local function manipulateeffect(tfmdata) end end if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) end parameters.factor = factor diff --git a/macros/luatex/generic/luaotfload/fontloader-font-one.lua b/macros/luatex/generic/luaotfload/fontloader-font-one.lua index a76c929859..5ef6e47497 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-one.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-one.lua @@ -592,15 +592,18 @@ local function copytotfm(data) parameters.descender = abs(metadata.descender or 0) parameters.units = 1000 -- - properties.spacer = spacer + properties.spacer = spacer + properties.format = fonts.formats[filename] or "type1" + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = fullname + properties.name = filename or fullname or fontname + properties.private = properties.private or data.private or privateoffset + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then properties.encodingbytes = 2 - properties.format = fonts.formats[filename] or "type1" - properties.filename = filename - properties.fontname = fontname - properties.fullname = fullname - properties.psname = fullname - properties.name = filename or fullname or fontname - properties.private = properties.private or data.private or privateoffset +end -- if next(characters) then return { diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua index aff4cc8c8d..b8e13f1070 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.111 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) @@ -486,23 +486,26 @@ local function copytotfm(data,cache_id) end end -- - parameters.designsize = (designsize/10)*65536 - parameters.minsize = (minsize /10)*65536 - parameters.maxsize = (maxsize /10)*65536 - parameters.ascender = abs(metadata.ascender or 0) - parameters.descender = abs(metadata.descender or 0) - parameters.units = units - parameters.vheight = metadata.defaultvheight + parameters.designsize = (designsize/10)*65536 + parameters.minsize = (minsize /10)*65536 + parameters.maxsize = (maxsize /10)*65536 + parameters.ascender = abs(metadata.ascender or 0) + parameters.descender = abs(metadata.descender or 0) + parameters.units = units + parameters.vheight = metadata.defaultvheight -- - properties.space = spacer + properties.space = spacer + properties.format = data.format or formats.otf + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = psname + properties.name = filename or fullname + properties.subfont = subfont + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then properties.encodingbytes = 2 - properties.format = data.format or formats.otf - properties.filename = filename - properties.fontname = fontname - properties.fullname = fullname - properties.psname = psname - properties.name = filename or fullname - properties.subfont = subfont +end -- -- properties.name = specification.name -- properties.sub = specification.sub diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua index 490f28de69..1f4806ee25 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua @@ -13,7 +13,7 @@ with plain it has to be so. This module is part of and discussion about improvements and functionality mostly happens on the mailing list.

-

The specification of OpenType is (or at least a decade ago was) kind of vague. +

The specification of OpenType is (or at least decades ago was) kind of vague. Apart from a lack of a proper free specifications there's also the problem that Microsoft and Adobe may have their own interpretation of how and in what order to apply features. In general the Microsoft website has more detailed specifications @@ -218,6 +218,7 @@ local copy_only_glyphs = nuts.copy_only_glyphs local count_components = nuts.count_components local set_components = nuts.set_components local get_components = nuts.get_components +local flush_components = nuts.flush_components --------------------------------------------------------------------------------------- @@ -251,7 +252,7 @@ local glue_code = nodecodes.glue local disc_code = nodecodes.disc local math_code = nodecodes.math local dir_code = nodecodes.dir -local localpar_code = nodecodes.localpar +local par_code = nodecodes.par local lefttoright_code = nodes.dirvalues.lefttoright local righttoleft_code = nodes.dirvalues.righttoleft @@ -488,6 +489,7 @@ local function markstoligature(head,start,stop,char) setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) + flush_components(start) return head, base end end @@ -500,9 +502,25 @@ end -- in the not discfound branch then. We now have skiphash too so we can be more -- selective if needed (todo). +-- we can have more granularity here but for now we only do a simple check + +local no_left_ligature_code = 1 +local no_right_ligature_code = 2 +local no_left_kern_code = 4 +local no_right_kern_code = 8 + +local has_glyph_option = node.direct.has_glyph_option or function(n,c) + if c == no_left_ligature_code or c == no_right_ligature_code then + return getattr(n,a_noligature) == 1 + else + return false + end +end + +-- in lmtx we need to check the components and can be slightly more clever + local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head - if getattr(start,a_noligature) == 1 then - -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first) + if has_glyph_option(start,no_right_ligature_code) then return head, start end if start == stop and getchar(start) == char then @@ -572,6 +590,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou break end end + flush_components(components) else -- discfound ... forget about marks .. probably no scripts that hyphenate and have marks local discprev, discnext = getboth(discfound) @@ -902,81 +921,89 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar = getchar(start) - local format = step.format - if format == "single" or type(kerns) == "table" then -- the table check can go - local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end + if has_glyph_option(start,no_right_kern_code) then + return head, start, false else - local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + local startchar = getchar(start) + local format = step.format + if format == "single" or type(kerns) == "table" then -- the table check can go + local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end end + return head, start, true end - return head, start, true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext = getnext(start) - if not snext then + if has_glyph_option(start,no_right_kern_code) then return head, start, false else - local prev = start - while snext do - local nextchar = ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then -- includes marks too when flag - prev = snext - snext = getnext(snext) - else - local krn = kerns[nextchar] - if not krn then - break - end - local format = step.format - if format == "pair" then - local a = krn[1] - local b = krn[2] - if a == true then - -- zero - elseif a then -- #a > 0 - local x, y, w, h = setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end + local snext = getnext(start) + if not snext then + return head, start, false + else + local prev = start + while snext do + local nextchar = ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then -- includes marks too when flag + prev = snext + snext = getnext(snext) + else + local krn = kerns[nextchar] + if not krn then + break end - if b == true then - -- zero - start = snext -- cf spec - elseif b then -- #b > 0 - local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection) + local format = step.format + if format == "pair" then + local a = krn[1] + local b = krn[2] + if a == true then + -- zero + elseif a then -- #a > 0 + local x, y, w, h = setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b == true then + -- zero + start = snext -- cf spec + elseif b then -- #b > 0 + local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start = snext -- cf spec + elseif forcepairadvance then + start = snext -- for testing, not cf spec + end + return head, start, true + elseif krn ~= 0 then + local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection) if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - start = snext -- cf spec - elseif forcepairadvance then - start = snext -- for testing, not cf spec - end - return head, start, true - elseif krn ~= 0 then - local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + return head, start, true + else -- can't happen + break end - return head, start, true - else -- can't happen - break end + else + break end - else - break end + return head, start, false end - return head, start, false end end @@ -1505,92 +1532,98 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup end function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping = currentlookup.mapping - if mapping == nil then - mapping = getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar = getchar(start) - local kerns = mapping[startchar] - if kerns then - local format = currentlookup.format - if format == "single" then - local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ? - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else -- needs checking .. maybe no kerns format for single - local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + -- we actually should check no_left_kern_code with next + if not has_glyph_option(start,no_right_kern_code) then + local mapping = currentlookup.mapping + if mapping == nil then + mapping = getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar = getchar(start) + local kerns = mapping[startchar] + if kerns then + local format = currentlookup.format + if format == "single" then + local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ? + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else -- needs checking .. maybe no kerns format for single + local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end end + return head, start, true end - return head, start, true end end return head, start, false end function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ? - local mapping = currentlookup.mapping - if mapping == nil then - mapping = getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext = getnext(start) - if snext then - local startchar = getchar(start) - local kerns = mapping[startchar] -- always 1 step - if kerns then - local prev = start - while snext do - local nextchar = ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev = snext - snext = getnext(snext) - else - local krn = kerns[nextchar] - if not krn then + -- we actually should check no_left_kern_code with next + if not has_glyph_option(start,no_right_kern_code) then + local mapping = currentlookup.mapping + if mapping == nil then + mapping = getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext = getnext(start) + if snext then + local startchar = getchar(start) + local kerns = mapping[startchar] -- always 1 step + if kerns then + local prev = start + while snext do + local nextchar = ischar(snext,currentfont) + if not nextchar then break end - local format = currentlookup.format - if format == "pair" then - local a = krn[1] - local b = krn[2] - if a == true then - -- zero - elseif a then - local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags? - if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end + if skiphash and skiphash[nextchar] then + prev = snext + snext = getnext(snext) + else + local krn = kerns[nextchar] + if not krn then + break end - if b == true then - -- zero - start = snext -- cf spec - elseif b then -- #b > 0 - local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections") + local format = currentlookup.format + if format == "pair" then + local a = krn[1] + local b = krn[2] + if a == true then + -- zero + elseif a then + local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags? + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b == true then + -- zero + start = snext -- cf spec + elseif b then -- #b > 0 + local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start = snext -- cf spec + elseif forcepairadvance then + start = snext -- for testing, not cf spec + end + return head, start, true + elseif krn ~= 0 then + local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn) if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) end - start = snext -- cf spec - elseif forcepairadvance then - start = snext -- for testing, not cf spec - end - return head, start, true - elseif krn ~= 0 then - local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + return head, start, true + else + break end - return head, start, true - else - break end end end @@ -3759,7 +3792,7 @@ do local initialrl = 0 - if getid(head) == localpar_code and start_of_par(head) then + if getid(head) == par_code and start_of_par(head) then initialrl = pardirstate(head) elseif direction == righttoleft_code then initialrl = -1 @@ -3913,7 +3946,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -3997,7 +4030,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -4108,7 +4141,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else diff --git a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua index c3fea6d460..78e8597b93 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['font-shp'] = { local tonumber, next = tonumber, next local concat = table.concat -local formatters = string.formatters +local formatters, lower = string.formatters, string.lower local otf = fonts.handlers.otf local afm = fonts.handlers.afm @@ -221,7 +221,7 @@ end local function loadstreams(cache,filename,sub,instance) local base = file.basename(filename) local name = file.removesuffix(base) - local kind = file.suffix(filename) + local kind = lower(file.suffix(filename)) local attr = lfs.attributes(filename) local size = attr and attr.size or 0 local time = attr and attr.modification or 0 diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua index 865f8e6e30..a2732aa5f2 100644 --- a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua +++ b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua @@ -163,8 +163,7 @@ local function mergecomposites(glyphs,shapes) return contours, points end --- for index=1,#glyphs do - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape = shapes[index] if shape then local components = shape.components @@ -659,7 +658,7 @@ local function repackpoints(glyphs,shapes) local result = { } -- reused local xpoints = { } -- reused local ypoints = { } -- reused - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape = shapes[index] if shape then local r = 0 diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua index df4f3593c2..0b220327c3 100644 --- a/macros/luatex/generic/luaotfload/fontloader-reference.lua +++ b/macros/luatex/generic/luaotfload/fontloader-reference.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2020-08-31 22:01 +-- merge date : 2020-12-30 16:42 do -- begin closure to overcome local limits and interference @@ -4939,6 +4939,7 @@ nuts.getkern=direct.getkern nuts.getlist=direct.getlist nuts.getnext=direct.getnext nuts.getoffsets=direct.getoffsets +nuts.getoptions=direct.getoptions or function() return 0 end nuts.getprev=direct.getprev nuts.getsubtype=direct.getsubtype nuts.getwidth=direct.getwidth @@ -5022,6 +5023,15 @@ local traverse_id=nuts.traverse_id local copy_node=nuts.copy_node local glyph_code=nodes.nodecodes.glyph local ligature_code=nodes.glyphcodes.ligature +do + local p=nodecodes.localpar or nodecodes.local_par + if p then + nodecodes.par=p + nodecodes[p]="par" + nodecodes.localpar=p + nodecodes.local_par=p + end +end do local get_components=node.direct.getcomponents local set_components=node.direct.setcomponents @@ -5074,11 +5084,14 @@ do end return 0 end + local function flush_components() + end nuts.set_components=set_components nuts.get_components=get_components nuts.copy_only_glyphs=copy_only_glyphs nuts.copy_no_components=copy_no_components nuts.count_components=count_components + nuts.flush_components=flush_components end nuts.uses_font=direct.uses_font do @@ -15147,7 +15160,7 @@ local function mergecomposites(glyphs,shapes) shape.components=nil return contours,points end - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local components=shape.components @@ -15577,7 +15590,7 @@ local function repackpoints(glyphs,shapes) local result={} local xpoints={} local ypoints={} - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local r=0 @@ -16840,7 +16853,7 @@ local function readfirst(f,offset) end return { readushort(f) } end -function readarray(f,offset) +local function readarray(f,offset) if offset then setposition(f,offset) end @@ -20766,7 +20779,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.111 +otf.version=3.112 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) @@ -21131,7 +21144,6 @@ local function copytotfm(data,cache_id) parameters.units=units parameters.vheight=metadata.defaultvheight properties.space=spacer - properties.encodingbytes=2 properties.format=data.format or formats.otf properties.filename=filename properties.fontname=fontname @@ -21139,6 +21151,9 @@ local function copytotfm(data,cache_id) properties.psname=psname properties.name=filename or fullname properties.subfont=subfont +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end properties.private=properties.private or data.private or privateoffset return { characters=characters, @@ -26617,6 +26632,7 @@ local copy_only_glyphs=nuts.copy_only_glyphs local count_components=nuts.count_components local set_components=nuts.set_components local get_components=nuts.get_components +local flush_components=nuts.flush_components local ischar=nuts.ischar local usesfont=nuts.uses_font local insert_node_after=nuts.insert_after @@ -26639,7 +26655,7 @@ local glue_code=nodecodes.glue local disc_code=nodecodes.disc local math_code=nodecodes.math local dir_code=nodecodes.dir -local localpar_code=nodecodes.localpar +local par_code=nodecodes.par local lefttoright_code=nodes.dirvalues.lefttoright local righttoleft_code=nodes.dirvalues.righttoleft local discretionarydisc_code=disccodes.discretionary @@ -26821,11 +26837,23 @@ local function markstoligature(head,start,stop,char) setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) + flush_components(start) return head,base end end +local no_left_ligature_code=1 +local no_right_ligature_code=2 +local no_left_kern_code=4 +local no_right_kern_code=8 +local has_glyph_option=node.direct.has_glyph_option or function(n,c) + if c==no_left_ligature_code or c==no_right_ligature_code then + return getattr(n,a_noligature)==1 + else + return false + end +end local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if getattr(start,a_noligature)==1 then + if has_glyph_option(start,no_right_ligature_code) then return head,start end if start==stop and getchar(start)==char then @@ -26889,6 +26917,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou break end end + flush_components(components) else local discprev,discnext=getboth(discfound) if discprev and discnext then @@ -27175,78 +27204,86 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip return head,start,false,false end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end + if has_glyph_option(start,no_right_kern_code) then + return head,start,false else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext=getnext(start) - if not snext then + if has_glyph_option(start,no_right_kern_code) then return head,start,false else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + return head,start,true + else + break end - return head,start,true - else - break end + else + break end - else - break end + return head,start,false end - return head,start,false end end function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) @@ -27676,89 +27713,93 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup return head,start,false,0,false end function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end end return head,start,false end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then break end - local format=currentlookup.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + local format=currentlookup.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + return head,start,true + else + break end - return head,start,true - else - break end end end @@ -29580,7 +29621,7 @@ do checkstep(head) end local initialrl=0 - if getid(head)==localpar_code and start_of_par(head) then + if getid(head)==par_code and start_of_par(head) then initialrl=pardirstate(head) elseif direction==righttoleft_code then initialrl=-1 @@ -34675,7 +34716,6 @@ local function copytotfm(data) parameters.descender=abs(metadata.descender or 0) parameters.units=1000 properties.spacer=spacer - properties.encodingbytes=2 properties.format=fonts.formats[filename] or "type1" properties.filename=filename properties.fontname=fontname @@ -34683,6 +34723,9 @@ local function copytotfm(data) properties.psname=fullname properties.name=filename or fullname or fontname properties.private=properties.private or data.private or privateoffset +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end if next(characters) then return { characters=characters, @@ -35993,7 +36036,7 @@ if not modules then modules={} end modules ['font-shp']={ } local tonumber,next=tonumber,next local concat=table.concat -local formatters=string.formatters +local formatters,lower=string.formatters,string.lower local otf=fonts.handlers.otf local afm=fonts.handlers.afm local pfb=fonts.handlers.pfb @@ -36186,7 +36229,7 @@ end local function loadstreams(cache,filename,sub,instance) local base=file.basename(filename) local name=file.removesuffix(base) - local kind=file.suffix(filename) + local kind=lower(file.suffix(filename)) local attr=lfs.attributes(filename) local size=attr and attr.size or 0 local time=attr and attr.modification or 0 @@ -37084,56 +37127,74 @@ local rules={ "FractionRuleThickness", "UnderbarRuleThickness", } -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dx) +local setmathparameters +local setmathcharacters +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - local function wdpatch(char) - if wsnap~=0 then - char.width=char.width+wdelta/2 - end + setmathcharacters=function() end - local function htpatch(char) - if hsnap~=0 then - local height=char.height - if height then - char.height=char.height+2*dy +else + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end - local character=characters[0x221A] - if character and character.next then - local char=character - local next=character.next - wdpatch(char) - htpatch(char) - while next do - char=characters[next] + setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next wdpatch(char) htpatch(char) - next=char.next - end - if char then - local v=char.vert_variants - if v then - local top=v[#v] - if top then - local char=characters[top.glyph] - htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end end end end end end -local shiftmode=CONTEXTLMTXMODE>0 +local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 local function manipulateeffect(tfmdata) local effect=tfmdata.properties.effect if effect then @@ -37205,7 +37266,7 @@ local function manipulateeffect(tfmdata) end end if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) end parameters.factor=factor diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua index 14a66da359..2d4e757bc0 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua @@ -4,19 +4,14 @@ -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-auxiliary", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - luaotfload = luaotfload or { } local log = luaotfload.log local logreport = log.report @@ -911,6 +906,53 @@ function aux.get_quad(font_id) return false end +----------------------------------------------------------------------- +--- Script/language fixup +----------------------------------------------------------------------- +local otftables = fonts.constructors.handlers.otf.tables +local function setscript(tfmdata, value) + if value then + local cleanvalue = string.lower(value) + local scripts = otftables and otftables.scripts + local properties = tfmdata.properties + if not scripts then + properties.script = cleanvalue + elseif scripts[value] then + properties.script = cleanvalue + else + properties.script = "dflt" + end + end + local resources = tfmdata.resources + local features = resources and resources.features + if features then + local properties = tfmdata.properties + local script, language = properties.script, properties.language + local script_found, language_found = false, false + for _, data in next, features do for _, feature_data in next, data do + local scr = feature_data[script] + if scr then + script_found = true + if scr[language] then + language_found = true + goto double_break + end + end + end end + ::double_break:: + if not script_found then properties.script = "dflt" end + if not language_found then properties.language = "dflt" end + end +end +fonts.constructors.features.otf.register { + name = "script", + initializers = { + base = setscript, + node = setscript, + plug = setscript, + }, +} + ----------------------------------------------------------------------- --- initialization ----------------------------------------------------------------------- diff --git a/macros/luatex/generic/luaotfload/luaotfload-case.lua b/macros/luatex/generic/luaotfload/luaotfload-case.lua new file mode 100644 index 0000000000..33bb1bc924 --- /dev/null +++ b/macros/luatex/generic/luaotfload/luaotfload-case.lua @@ -0,0 +1,239 @@ +local unicode_data = require'luaotfload-unicode' + +local mapping_tables = unicode_data.casemapping +local soft_dotted = unicode_data.soft_dotted +local ccc = unicode_data.ccc + +local uppercase = mapping_tables.uppercase +local lowercase = mapping_tables.lowercase +local cased = mapping_tables.cased +local case_ignorable = mapping_tables.case_ignorable + +local otfregister = fonts.constructors.features.otf.register + +local direct = node.direct +local is_char = direct.is_char +local has_glyph = direct.has_glyph +local uses_font = direct.uses_font +local getnext = direct.getnext +local setchar = direct.setchar +local setdisc = direct.setdisc +local getdisc = direct.getdisc +local getfield = direct.getfield +local remove = direct.remove +local copy = direct.copy +local insert_after = direct.insert_after +local traverse = direct.traverse + +local disc = node.id'disc' + +--[[ We make some implicit assumptions about contexts in SpecialCasing.txt here which happened to be true when I wrote the code: +-- +-- * Before_Dot only appears as Not_Before_Dot +-- * No other context appears with Not_ +-- * Final_Sigma is never language dependent +-- * Other contexts are always language dependent +-- * The only languages with special mappings are Lithuanian (lt/"LTH "/lit), Turkish (tr/"TRK "/tur), and Azeri/Azerbaijani (az/"AZE "/aze) +]] + +local font_lang = setmetatable({}, {__index = function(t, fid) + local f = font.getfont(fid) + local lang = f.specification.features.normal.language + lang = lang == 'lth' and 'lt' or lang == 'trk' and 'tr' or lang == 'aze' and 'az' or false + t[fid] = lang + return lang +end}) + +local function is_Final_Sigma(font, mapping, n, after) + mapping = mapping.Final_Sigma + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + if not case_ignorable[char] then + return not cased[char] and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_More_Above(font, mapping, n, after) + mapping = mapping.More_Above + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return false + elseif char_ccc == 230 then + return mapping + end + n = getnext(n) + else + return false + end + end + n, after = after + until not n + return false +end + +local function is_Not_Before_Dot(font, mapping, n, after) + mapping = mapping.Not_Before_Dot + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return mapping + elseif char_ccc == 230 then + return char ~= 0x0307 and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_Language_Mapping(font, mapping, n, after, seen_soft_dotted, seen_I) + if not mapping then return false end + if seen_soft_dotted then + local mapping = mapping.After_Soft_Dotted + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + if seen_I then + local mapping = mapping.After_I + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + return is_More_Above(font, mapping, n, after) or is_Not_Before_Dot(font, mapping, n, after) or mapping._ -- Might be nil +end + +local function process(table) + local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I) + local lang = font_lang[font] + local n = head + while n do + do + local new = has_glyph(n) + if n ~= new then + seen_cased, seen_soft_dotted, seen_I = nil + end + n = new + end + if not n then break end + local char, id = is_char(n, font) + if char then + local mapping = table[char] + if mapping then + if tonumber(mapping) then + setchar(n, mapping) + else + mapping = seen_cased and is_Final_Sigma(font, mapping, n, after) + or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I) + or mapping._ + if #mapping == 0 then + head, n = remove(head, n) + goto continue + else + setchar(n, mapping[1]) + for i=2, #mapping do + head, n = insert_after(head, n, copy(n)) + setchar(n, mapping[i]) + end + end + end + end + if not case_ignorable[char] then + seen_cased = cased[char] or nil + end + local char_ccc = ccc[char] + if not char_ccc or char_ccc == 230 then + seen_I = char == 0x49 or nil + seen_soft_dotted = soft_dotted[char] + end + elseif id == disc and uses_font(n, font) then + local pre, post, rep = getdisc(n) + local after = getnext(n) + pre, post, rep, seen_cased, seen_soft_dotted, seen_I = + processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I), + processor(post, font, after), + processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I) + setdisc(n, pre, post, rep) + else + seen_cased, seen_soft_dotted, seen_I = nil + end + n = getnext(n) + ::continue:: + end + return head, seen_cased, seen_soft_dotted, seen_I + end + return function(head, font) return (processor(head, font)) end +end + +local upper_process = process(uppercase) +otfregister { + name = 'upper', + description = 'Map to uppercase', + default = false, + processors = { + position = 1, + plug = upper_process, + node = upper_process, + base = upper_process, + }, +} + +local lower_process = process(lowercase) +otfregister { + name = 'lower', + description = 'Map to lowercase', + default = false, + processors = { + position = 1, + plug = lower_process, + node = lower_process, + base = lower_process, + }, +} diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua index e8a8e996a8..c1f8a63a8e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua @@ -3,21 +3,16 @@ -- DESCRIPTION: part of luaotfload / font colors ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-colors", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", copyright = "Luaotfload Development Team" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - --[[doc-- buggy coloring with the pre_output_filter when expansion is enabled diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf index 85768faf2f..52137882d4 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf and b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua index 8f04190a43..e5e1ed24f0 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua @@ -5,18 +5,14 @@ -- AUTHOR: Dohyun Kim ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-configuration", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - ------------------------------ local status_file = "luaotfload-status" diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua index 6d0bcff414..da2d9965a3 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-database.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / luaotfload-tool / font database ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-database", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", copyright = "Luaotfload Development Team", } - - if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) - end end --[[doc-- @@ -2335,8 +2331,7 @@ local path_separator = os.type == "windows" and ";" or ":" --[[doc-- collect_font_filenames_texmf -- Scan texmf tree for font files - relying on the kpathsea variables $OPENTYPEFONTS and $TTFONTS of - texmf.cnf. + relying on kpathsea search paths for the respective file types. The current working directory comes as “.” (texlive) or absolute path (miktex) and will always be filtered out. @@ -2362,16 +2357,20 @@ local function collect_font_filenames_texmf () end end - fontdirs = kpseexpand_path "$OPENTYPEFONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$AFMFONTS" + local show_path = kpse.show_path - if stringis_empty (fontdirs) then - return { } + local function expanded_path (file_type) + return kpseexpand_path (show_path (file_type)) end - local tasks = filter_out_pwd (filesplitpath (fontdirs)) + local fontdirs = expanded_path "opentype fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "truetype fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "type1 fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "afm" + + fontdirs = filesplitpath (fontdirs) or { } + + local tasks = filter_out_pwd (fontdirs) logreport ("both", 3, "db", "Initiating scan of %d directories.", #tasks) diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua index be3183cf65..366c7c98ec 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua @@ -5,19 +5,14 @@ -- AUTHOR: Philipp Gesang ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-diagnostics", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload-tool submodule / diagnostics", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - local names = fonts.names local kpse = require "kpse" diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua index b57934fdb6..33083045d4 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua @@ -4,20 +4,16 @@ ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-dvi", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / DVI", license = "GPL v2.0", author = "Marcel Krüger", copyright = "Luaotfload Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local getfont = font.getfont local setfont = node.direct.setfont local getdisc = node.direct.getdisc diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua index d1d4e478c8..73993eead8 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / embolden ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-embolden", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / embolden", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local otffeatures = fonts.constructors.newfeatures "otf" local function enableembolden(tfmdata, _, embolden) diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua index eee107c709..17bd7ca404 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / fallback ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-fallback", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / fallback", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local nodenew = node.direct.new local getfont = font.getfont local setfont = node.direct.setfont diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua index 2d83df10ff..67c9f93565 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-features.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua @@ -3,21 +3,16 @@ -- DESCRIPTION: part of luaotfload / font features ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-features", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / features", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", copyright = "PRAGMA ADE / ConTeXt Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - local type = type local next = next local tonumber = tonumber @@ -45,12 +40,18 @@ local otf = handlers.otf local config = config or { luaotfload = { run = { } } } -local as_script = true -local normalize = function () end +local as_script = config.luaotfload.run.live +local normalize -if config.luaotfload.run.live ~= false then +if as_script then + function normalize(features) + return { + axis = features and features.axis, + instance = features and features.instance, + } + end +else normalize = otf.features.normalize - as_script = false end --[[HH (font-xtx) -- @@ -663,7 +664,7 @@ end do local function mathfontdimen(tfmdata, _, value) - if not next(tfmdata.mathparameters) then return end + if not (tfmdata.mathparameters and next(tfmdata.mathparameters)) then return end local parameters = tfmdata.parameters local mathparameters = tfmdata.mathparameters if value == 'xetex' then diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua index b8ab343402..69195603ed 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua @@ -4,19 +4,13 @@ -- AUTHOR: Ulrike Fischer, ----------------------------------------------------------------------- -local ProvidesLuaModule = { +if luaotfload_module then luaotfload_module { name = "luaotfload-filelist", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" -} - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - +} end --[[doc-- diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua index 19f5c2082b..aefc8369c6 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua @@ -1,12 +1,14 @@ -local ProvidesLuaModule = { +if luaotfload_module then + luaotfload_module { name = "luaotfload-glyphlist", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / autogenerated glyphlist", copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt", original = "Adobe Glyph List, version 2.0, September 20, 2002", dataonly = true -} + } +end if context then logs.report("fatal error","this module is not for context") diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua index 37ada59d00..5be4acfa65 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / HarfBuzz / font definition ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-define", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / HarfBuzz font loading", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", copyright = "Luaotfload Development Team", } - - if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) - end end local unpack = string.unpack diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua index 6759747fbf..c40aa3b72e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / HarfBuzz / fontloader plugin ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-plug", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / HarfBuzz shaping", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", copyright = "Luaotfload Development Team", } - - if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) - end end local hb = luaotfload.harfbuzz @@ -36,6 +32,7 @@ local direct = node.direct local tonode = direct.tonode local todirect = direct.todirect local traverse = direct.traverse +local traverse_list = direct.traverse_list local insertbefore = direct.insert_before local insertafter = direct.insert_after local protectglyph = direct.protect_glyph @@ -46,6 +43,7 @@ local removenode = direct.remove local copynodelist = direct.copy_list local ischar = direct.is_char local uses_font = direct.uses_font +local length = direct.length local getattrs = direct.getattributelist local setattrs = direct.setattributelist @@ -78,13 +76,15 @@ local getsubtype = direct.getsubtype local setsubtype = direct.setsubtype local getwidth = direct.getwidth local setwidth = direct.setwidth +local setlist = direct.setlist local is_char = direct.is_char local tail = direct.tail +local getboth = direct.getboth +local setlink = direct.setlink local properties = direct.get_properties_table() -local imgnode = img.node - +local hlist_t = node.id("hlist") local disc_t = node.id("disc") local glue_t = node.id("glue") local glyph_t = node.id("glyph") @@ -94,7 +94,10 @@ local localpar_t = node.id("local_par") local whatsit_t = node.id("whatsit") local pdfliteral_t = node.subtype("pdf_literal") +local line_t = 1 local explicitdisc_t = 1 +local firstdisc_t = 4 +local seconddisc_t = 5 local fontkern_t = 0 local italiccorr_t = 3 local regulardisc_t = 3 @@ -179,8 +182,12 @@ local function itemize(head, fontid, direction) local currdir = direction or 0 local lastskip, lastdir = true local lastrun = {} + local lastdisc + local in_disc - for n, id, subtype in direct.traverse(head) do + for n, id, subtype in traverse(head) do + if in_disc == n then in_disc = nil end + local disc local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER local skip = lastskip local props = properties[n] @@ -189,8 +196,9 @@ local function itemize(head, fontid, direction) code = 0x200C -- skip = false -- Not sure about this, but lastskip should be a bit faster elseif id == glyph_t then - if is_char(n) and getfont(n) == fontid then - code = getchar(n) + local char = is_char(n, fontid) + if char then + code = char skip = false else skip = true @@ -199,8 +207,28 @@ local function itemize(head, fontid, direction) code = 0x0020 -- SPACE elseif id == disc_t then if uses_font(n, fontid) then - code = 0x00AD -- SOFT HYPHEN + local _, _, rep, _, _, rep_tail = getdisc(n, true) + setfield(n, 'replace', nil) + local prev, next = getboth(n) + in_disc = next + disc = { + disc = n, + anchor_cluster = #codes - (lastrun.start or 0) + 1, + after_cluster = #codes - (lastrun.start or 0) + 1 + length(rep), + } + if rep then + setlink(rep_tail, next) + setnext(n, rep) -- This one is just to keep the loop going + n = rep + else + n = next + end + setlink(prev, n) + code = nil skip = false + if not prev then + head = n + end else skip = true end @@ -220,26 +248,39 @@ local function itemize(head, fontid, direction) currdir = getdirection(n) end - codes[#codes + 1] = code + local ncodes = #codes -- Necessary to count discs correctly + codes[ncodes + 1] = code - if lastdir ~= currdir or lastskip ~= skip then + if (disc or not in_disc) and (lastdir ~= currdir or lastskip ~= skip) then + if disc then + disc.after_cluster = disc.after_cluster - disc.anchor_cluster + disc.anchor_cluster = 0 + end lastrun.after = n lastrun = { - start = #codes, - len = 1, + start = ncodes + 1, + len = code and 1 or 0, font = fontid, dir = currdir == 1 and dir_rtl or dir_ltr, skip = skip, codes = codes, + discs = disc, } runs[#runs + 1] = lastrun - lastdir, lastskip = currdir, skip - else + lastdir, lastskip, lastdisc = currdir, skip, disc + elseif code then lastrun.len = lastrun.len + 1 + elseif disc then + if lastdisc then + lastdisc.next = disc + lastdisc = disc + else + lastrun.discs, lastdisc = disc, disc + end end end - return runs + return head, runs end @@ -260,7 +301,6 @@ local function makesub(run, codes, nodelist) font = run.font, dir = run.dir, fordisc = true, - node = nodelist, codes = codes, } local glyphs @@ -294,14 +334,12 @@ end function shape(head, firstnode, run) local node = firstnode local codes = run.codes - local offset = run.start - local nodeindex = offset - run.start = offset + local offset = run.start - 1 -- -1 because we want the cluster local len = run.len local fontid = run.font local dir = run.dir - local fordisc = run.fordisc - local cluster = offset - 2 + local cluster + local discs = (not run.fordisc) and run.discs local fontdata = font.getfont(fontid) local hbdata = fontdata.hb @@ -323,7 +361,7 @@ function shape(head, firstnode, run) buf:set_script(script) buf:set_language(lang) buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS) - buf:add_codepoints(codes, offset - 1, len) + buf:add_codepoints(codes, offset, len) local hscale = hbdata.hscale local vscale = hbdata.vscale @@ -333,7 +371,7 @@ function shape(head, firstnode, run) features = table.merged(features) -- We don't want to modify the global features local current_features = {} local n = node - for i = offset-1, offset+len-2 do + for i = offset, offset+len-1 do local props = properties[n] or empty_table if props then local local_feat = props.glyph_features or empty_table @@ -371,187 +409,260 @@ function shape(head, firstnode, run) local glyphs = buf:get_glyphs() + local break_glyph, break_cluster, break_node = 1, offset, node + local disc_glyph, disc_cluster, disc_node + local disc_cluster local i = 0 - while i < #glyphs do - i = i + 1 - local glyph = glyphs[i] - - -- Calculate the Unicode code points of this glyph. If cluster did not - -- change then this is a glyph inside a complex cluster and will be - -- handled with the start of its cluster. - if cluster ~= glyph.cluster then - cluster = glyph.cluster - for i = nodeindex, cluster do node = getnext(node) end - nodeindex = cluster + 1 - local hex = "" - local str = "" - local nextcluster - for j = i+1, #glyphs do - nextcluster = glyphs[j].cluster - if cluster ~= nextcluster then - glyph.nglyphs = j - i - goto NEXTCLUSTERFOUND -- break - end - end -- else -- only executed if the loop reached the end without - -- finding another cluster - nextcluster = offset + len - 1 - glyph.nglyphs = #glyphs + 1 - i - ::NEXTCLUSTERFOUND:: -- end - glyph.nextcluster = nextcluster - do - local node = node - for j = cluster,nextcluster-1 do - local id = getid(node) - if id == glyph_t or (id == glue_t and getsubtype(node) == spaceskip_t) then - local code = codes[j + 1] - hex = hex..to_utf16_hex(code) - str = str..utf8.char(code) - end + local glyph + -- The following is a repeat {...} while glyph {...} loop. + while true do + repeat + i = i+1 + glyph = glyphs[i] + until not glyph or glyph.cluster ~= cluster + do + local oldcluster = cluster + cluster = glyph and glyph.cluster or offset + len + if oldcluster then + for _ = oldcluster+1, cluster do + node = getnext(node) end - glyph.tounicode = hex - glyph.string = str end - if not fordisc then - local discindex = nil - local disc = node - for j = cluster + 1, nextcluster do - local props = properties[disc] - if (not (props and props.zwnj)) and getid(disc) == disc_t then - discindex = j - break + end + + -- Is this a safe breakpoint? + if discs and ((not glyph) or codes[cluster] == 0x20 or codes[cluster+1] == 0x20 or codes[cluster+1] == 0xFFFC + or not unsafetobreak(glyph)) then + -- Should we change the discretionary state? + local anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster + local saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset + while disc_cluster and after_cluster <= cluster + or not disc_cluster and anchor_cluster <= cluster do + if disc_cluster then + if not saved_after and saved_anchor < cluster then + saved_after = discs.next.after_cluster + offset + if saved_after > cluster then + saved_after, after_cluster = after_cluster, saved_after + break + end + elseif saved_after then + saved_after, after_cluster = after_cluster, saved_after end - disc = getnext(disc) - end - if discindex then - -- Discretionary found. - local startindex, stopindex = nil, nil - local startglyph, stopglyph = nil, nil - - -- Find the previous glyph that is safe to break at. - local startglyph = i - while startglyph > 1 - and codes[glyphs[startglyph - 1].cluster + 1] ~= 0x20 - and codes[glyphs[startglyph - 1].cluster + 1] ~= 0xFFFC - and (unsafetobreak(glyphs[startglyph]) - or glyphs[startglyph].cluster == glyphs[startglyph-1].cluster) do - startglyph = startglyph - 1 + local rep_glyphs = table.move(glyphs, disc_glyph, i - 1, 1, {}) + for j = 1, #rep_glyphs do + local glyph = rep_glyphs[j] + glyph.cluster = glyph.cluster - disc_cluster + glyph.nextcluster = glyph.nextcluster - disc_cluster end - -- Get the corresponding character index. - startindex = glyphs[startglyph].cluster + 1 - - -- Find the next glyph that is safe to break at. - stopglyph = i + 1 - local lastcluster = glyphs[i].cluster - while stopglyph <= #glyphs - and codes[glyphs[stopglyph].cluster + 1] ~= 0x20 - and codes[glyphs[stopglyph].cluster + 1] ~= 0xFFFC - and (unsafetobreak(glyphs[stopglyph]) - or lastcluster == glyphs[stopglyph].cluster) do - lastcluster = glyphs[stopglyph].cluster - stopglyph = stopglyph + 1 + do + local cluster_offset = disc_cluster - cluster + (saved_after and 2 or 1) -- The offset the glyph indices will move + for j = i, #glyphs do + local glyph = glyphs[j] + glyph.cluster = glyph.cluster + cluster_offset + end + len = len + cluster_offset + table.move(glyphs, i, #glyphs + i - disc_glyph, disc_glyph + (saved_after and 2 or 1)) + + local discs = discs.next + while discs do + discs.anchor_cluster = discs.anchor_cluster + cluster_offset + discs.after_cluster = discs.after_cluster + cluster_offset + discs = discs.next + end end - stopindex = stopglyph <= #glyphs and glyphs[stopglyph].cluster + 1 - or offset + len - - local startnode, stopnode = node, node - for j=nodeindex - 1, startindex, -1 do - startnode = getprev(startnode) + local pre, post, _, _, lastpost, _ = getdisc(discs.disc, true) + local precodes, postcodes, repcodes = {}, {} + table.move(codes, disc_cluster + 1, anchor_cluster, 1, precodes) + for n in traverse(pre) do + precodes[#precodes + 1] = is_char(n, fontid) or 0xFFFC end - for j=nodeindex + 1, stopindex do - stopnode = getnext(stopnode) + for n in traverse(post) do + postcodes[#postcodes + 1] = is_char(n, fontid) or 0xFFFC end + table.move(codes, after_cluster + 1, cluster, #postcodes + 1, postcodes) - glyphs[startglyph] = glyph - glyph.cluster = startindex - 1 - glyph.nextcluster = startindex - for j = stopglyph, #glyphs do - local glyph = glyphs[j] - glyph.cluster = glyph.cluster - (stopindex - startindex) + 1 + if saved_after then + repcodes = table.move(codes, disc_cluster + 1, cluster, 1, {}) + table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 3) + codes[disc_cluster + 1], codes[disc_cluster + 2] = 0xFFFC, 0xFFFC + else + table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 2) + codes[disc_cluster + 1] = 0xFFFC end - len = len - (stopindex - startindex) + 1 - table.move(glyphs, stopglyph, #glyphs + stopglyph - startglyph - 1, startglyph + 1) - local subcodes, subindex = {} do - local node = startnode - while node ~= stopnode do - if node == disc then - subindex = #subcodes - startindex = startindex + 1 - node = getnext(node) - elseif getid(node) == disc_t then - local oldnode = node - startnode, node = removenode(startnode, node) - freenode(oldnode) - tableremove(codes, startindex) - else - subcodes[#subcodes + 1] = tableremove(codes, startindex) - node = getnext(node) - end + local iter = disc_node + for _ = disc_cluster, anchor_cluster-1 do iter = getnext(iter) end + if iter ~= disc_node then + local newpre = copynodelist(disc_node, iter) + setlink(tail(newpre), pre) + pre = newpre + end + for _ = anchor_cluster, after_cluster-1 do iter = getnext(iter) end + if post then + setlink(lastpost, copynodelist(iter, node)) + else + post = copynodelist(iter, node) end end - - local pre, post, rep, lastpre, lastpost, lastrep = getdisc(disc, true) - local precodes, postcodes, repcodes = {}, {}, {} - table.move(subcodes, 1, subindex, 1, repcodes) - for n, id, subtype in traverse(rep) do - repcodes[#repcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC - end - table.move(subcodes, subindex + 1, #subcodes, #repcodes + 1, repcodes) - table.move(subcodes, 1, subindex, 1, precodes) - for n, id, subtype in traverse(pre) do - precodes[#precodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC - end - for n, id, subtype in traverse(post) do - postcodes[#postcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC - end - table.move(subcodes, subindex + 1, #subcodes, #postcodes + 1, postcodes) - if startnode ~= disc then - local newpre = copynodelist(startnode, disc) - setnext(tail(newpre), pre) - pre = newpre + local prev = getprev(disc_node) + if disc_cluster ~= cluster then + setprev(disc_node, nil) + setnext(getprev(node), nil) end - if post then - setnext(lastpost, copynodelist(getnext(disc), stopnode)) - else - post = copynodelist(getnext(disc), stopnode) + setlink(prev, discs.disc, node) + if disc_node == firstnode then + firstnode = discs.disc + if head == disc_node then + head = firstnode + end end - if startnode ~= disc then - local predisc = getprev(disc) - setnext(predisc, rep) - setprev(rep, predisc) - if firstnode == startnode then - firstnode = disc + glyphs[disc_glyph] = { + replace = { + glyphs = rep_glyphs, + head = disc_node ~= node and disc_node or nil, + run = { + start = 1, + font = run.font, + dir = run.dir, + }, + }, + pre = makesub(run, precodes, pre), + post = makesub(run, postcodes, post), + cluster = disc_cluster, + nextcluster = disc_cluster + 1, + codepoint = 0xFFFC, + } + if saved_after then + local next_disc = discs.next + setlink(discs.disc, next_disc.disc, node) + local next_pre, next_post, _, _, next_lastpost, _ = getdisc(next_disc.disc, true) + local next_rep = copynodelist(next_pre) + -- Let's play the game again. We need three parts: + -- The pre and post branches in the outer post branch + local next_precodes, next_postcodes, next_repcodes = {}, {}, {} + do + local saved_offset = length(post) - cluster + local saved_anchor, saved_after = saved_anchor + saved_offset, saved_after + saved_offset + table.move(postcodes, 1, saved_anchor, 1, next_precodes) + for n in traverse(next_pre) do + next_precodes[#next_precodes + 1] = is_char(n, fontid) or 0xFFFC + end + for n in traverse(next_post) do + next_postcodes[#next_postcodes + 1] = is_char(n, fontid) or 0xFFFC + end + table.move(postcodes, saved_after + 1, #postcodes, #next_postcodes + 1, next_postcodes) + + local iter = post + for _ = 1, saved_anchor do iter = getnext(iter) end + if iter ~= post then + local newpre = copynodelist(post, iter) + setlink(tail(newpre), next_pre) + next_pre = newpre + end + for _ = saved_anchor, saved_after - 1 do iter = getnext(iter) end + if next_post then + setlink(next_lastpost, copynodelist(iter)) + else + next_post = copynodelist(iter) + end end - if startnode == head then - head = disc - else - local before = getprev(startnode) - setnext(before, disc) - setprev(disc, before) + -- The pre branch in the outer replace branch. The post branch is implicitly the same as the previous one + do + local saved_anchor = saved_anchor - disc_cluster + table.move(repcodes, 1, saved_anchor, 1, next_repcodes) + for n in traverse(next_rep) do + next_repcodes[#next_repcodes + 1] = is_char(n, fontid) or 0xFFFC + end + + local rep = glyphs[disc_glyph].replace.head + local iter = rep + for _ = 1, saved_anchor do iter = getnext(iter) end + if iter ~= rep then + local newpre = copynodelist(rep, iter) + setlink(tail(newpre), next_rep) + next_rep = newpre + end end - setprev(startnode, nil) - rep = startnode - lastrep = lastrep or predisc + setsubtype(discs.disc, firstdisc_t) + setsubtype(next_disc.disc, seconddisc_t) + discs = discs.next + disc_glyph = disc_glyph + 1 + disc_cluster = disc_cluster + 1 + glyphs[disc_glyph] = { + replace = makesub(run, next_repcodes, next_rep), + pre = makesub(run, next_precodes, next_pre), + post = makesub(run, next_postcodes, next_post), + cluster = disc_cluster, + nextcluster = disc_cluster + 1, + codepoint = 0xFFFC, + } + end + i = disc_glyph + 1 + assert(node == getnext(discs.disc)) + cluster = disc_cluster + 1 + + disc_cluster = nil + discs = discs.next + while discs and discs.anchor_cluster + offset < cluster do + freenode(discs.disc) + discs = discs.next end - if getnext(disc) ~= stopnode then - setnext(getprev(stopnode), nil) - setprev(stopnode, disc) - setprev(getnext(disc), lastrep) - setnext(lastrep, getnext(disc)) - rep = rep or getnext(disc) - setnext(disc, stopnode) + if not discs then break end + anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster + saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset + elseif anchor_cluster == cluster then + disc_glyph, disc_cluster, disc_node = i, cluster, node + else + disc_glyph, disc_cluster, disc_node = break_glyph, break_cluster, break_node + end + end + break_glyph, break_cluster, break_node = i, cluster, node + end + + if not glyph then break end + + local nextcluster + for j = i+1, #glyphs do + nextcluster = glyphs[j].cluster + if cluster ~= nextcluster then + glyph.nglyphs = j - i + goto NEXTCLUSTERFOUND -- break + end + end -- else -- only executed if the loop reached the end without + -- finding another cluster + nextcluster = offset + len + glyph.nglyphs = #glyphs + 1 - i + ::NEXTCLUSTERFOUND:: -- end + glyph.nextcluster = nextcluster + + local disc, discindex + -- Calculate the Unicode code points of this glyph. If cluster did not + -- change then this is a glyph inside a complex cluster and will be + -- handled with the start of its cluster. + do + local hex = "" + local str = "" + local node = node + for j = cluster+1,nextcluster do + local char, id = is_char(node, fontid) + if char then + -- assert(char == codes[j]) + hex = hex .. to_utf16_hex(char) + str = str .. utf8.char(char) + elseif not discindex and id == disc_t then + local props = properties[disc] + if not (props and props.zwnj) then + disc, discindex = node, j end - glyph.replace = makesub(run, repcodes, rep) - glyph.pre = makesub(run, precodes, pre) - glyph.post = makesub(run, postcodes, post) - i = startglyph - node = disc - cluster = glyph.cluster - nodeindex = cluster + 1 end + node = getnext(node) end + glyph.tounicode = hex + glyph.string = str + end + if not fordisc and discindex then end end return head, firstnode, glyphs, run.len - len @@ -587,7 +698,7 @@ local function color_to_rgba(color) end end --- Cache of color glyph PNG data for bookkeeping, only because I couldn’t +-- Cache of color glyph PNG data for bookkeeping, only because I couldn't -- figure how to make the engine load the image from the binary data directly. local pngcache = {} local pngcachefiles = {} @@ -672,7 +783,7 @@ local function tonodes(head, node, run, glyphs) end local gid = glyph.codepoint local char = nominals[gid] or gid_offset + gid - local id = getid(node) + local orig_char, id = is_char(node, fontid) if glyph.replace then -- For discretionary the glyph itself is skipped and a discretionary node @@ -681,17 +792,12 @@ local function tonodes(head, node, run, glyphs) setdisc(node, tonodes(pre.head, pre.head, pre.run, pre.glyphs), tonodes(post.head, post.head, post.run, post.glyphs), - tonodes(rep.head, rep.head, rep.run, rep.glyphs)) + (tonodes(rep.head, rep.head, rep.run, rep.glyphs))) node = getnext(node) nodeindex = nodeindex + 1 - elseif glyph.skip then - local oldnode = node - head, node = removenode(head, node) - freenode(oldnode) - nodeindex = nodeindex + 1 else if lastprops and lastprops.zwnj and nodeindex == glyph.cluster + 1 then - elseif id == glyph_t then + elseif orig_char then local done local fontglyph = fontglyphs[gid] local character = characters[char] @@ -717,7 +823,7 @@ local function tonodes(head, node, run, glyphs) character.depth = layerchar.depth end -- color_index has a special value, 0x10000, that mean use text - -- color, we don’t check for it here explicitly since we will + -- color, we don't check for it here explicitly since we will -- get nil anyway. local color = palette[layer.color_index] if not color or color.alpha ~= 0 then @@ -787,7 +893,7 @@ local function tonodes(head, node, run, glyphs) -- Color bitmap font with no glyph outlines (like Noto -- Color Emoji) but has no bitmap for current glyph (most likely -- `.notdef` glyph). The engine does not know how to embed such - -- fonts, so we don’t want them to reach the backend as it will cause + -- fonts, so we don't want them to reach the backend as it will cause -- a fatal error. We use `nullfont` instead. That is a hack, but I -- think it is good enough for now. We could make the glyph virtual -- with empty commands suh that LuaTeX ignores it, but we still want @@ -799,7 +905,7 @@ local function tonodes(head, node, run, glyphs) end end if not done then - local oldcharacter = characters[getchar(node)] + local oldcharacter = characters[orig_char] -- If the glyph index of current font character is the same as shaped -- glyph, keep the node char unchanged. Helps with primitives that -- take characters as input but actually work on glyphs, like @@ -824,7 +930,7 @@ local function tonodes(head, node, run, glyphs) -- overfull messages, otherwise it will be trying to print our -- invalid pseudo Unicode code points. -- If the string is empty it means this glyph is part of a larger - -- cluster and we don’t to print anything for it as the first glyph + -- cluster and we don't to print anything for it as the first glyph -- in the cluster will have the string of the whole cluster. local props = properties[node] if not props then @@ -837,7 +943,7 @@ local function tonodes(head, node, run, glyphs) -- * Find how many characters in this cluster and how many glyphs, -- * If there is more than 0 characters -- * One glyph: one to one or one to many mapping, can be - -- represented by font’s /ToUnicode + -- represented by font's /ToUnicode -- * More than one: many to one or many to many mapping, can be -- represented by /ActualText spans. -- * If there are zero characters, then this glyph is part of complex @@ -883,7 +989,7 @@ local function tonodes(head, node, run, glyphs) end elseif id == kern_t and getsubtype(node) == italiccorr_t then -- If this is an italic correction node and the previous node is a - -- glyph, update its kern value with the glyph’s italic correction. + -- glyph, update its kern value with the glyph's italic correction. local prevchar, prevfontid = ischar(getprev(node)) if prevfontid == fontid and prevchar and prevchar > 0 then local italic = characters[prevchar].italic @@ -919,8 +1025,8 @@ local function shape_run(head, current, run) end function process(head, font, _attr, direction) - local newhead, current = head, head - local runs = itemize(head, font, direction) + local newhead, runs = itemize(head, font, direction) + local current = newhead local offset = 0 for i = 1,#runs do @@ -954,29 +1060,39 @@ local function post_process(head) if startactual then local actualtext = "/Span<>>BDC" head = insertbefore(head, n, pageliteral(actualtext)) + props[startactual_p] = nil end if endactual then head = insertafter(head, n, pageliteral("EMC")) + props[endactual_p] = nil end local replace = getfield(n, "replace") if replace then setfield(n, "replace", post_process(replace)) end + end + return head +end - local subhead = getfield(n, "head") - if subhead then - setfield(n, "head", post_process(subhead)) +local function post_process_vlist(head) + for n, id, subtype, list in traverse_list(head) do + if id == hlist_t and subtype == line_t then + setlist(n, post_process(list)) end end - return head + return true end -local function post_process_nodes(head, groupcode) +local function post_process_nodes(head) return tonode(post_process(todirect(head))) end +local function post_process_vlist_nodes(head) + return tonode(post_process_vlist(todirect(head))) +end + local function run_cleanup() -- Remove temporary PNG files that we created, if any. -- FIXME: It would be nice if we wouldn't need this @@ -1032,29 +1148,10 @@ end fonts.handlers.otf.registerplugin('harf', process) --- luatexbase does not know how to handle `wrapup_run` callback, teach it. --- TODO: Move these into ltluatex -luatexbase.callbacktypes.wrapup_run = 1 -- simple -luatexbase.callbacktypes.glyph_info = 1 -- simple - -local base_callback_descriptions = luatexbase.callback_descriptions -local base_add_to_callback = luatexbase.add_to_callback -local base_remove_from_callback = luatexbase.remove_from_callback - --- Remove all existing functions from given callback, insert ours, then --- reinsert the removed ones, so ours takes a priority. -local function add_to_callback(name, func) - local saved_callbacks = {}, ff, dd - for k, v in next, base_callback_descriptions(name) do - saved_callbacks[k] = { base_remove_from_callback(name, v) } - end - base_add_to_callback(name, func, "Harf "..name.." callback") - for _, v in next, saved_callbacks do - base_add_to_callback(name, v[1], v[2]) - end -end +local add_to_callback = luatexbase.add_to_callback -add_to_callback('pre_output_filter', post_process_nodes) -- FIXME: Wrong callback, but I want to get rid of the whole function anyway -add_to_callback('wrapup_run', run_cleanup) -add_to_callback('finish_pdffile', set_tounicode) -add_to_callback('glyph_info', get_glyph_info) +add_to_callback('post_linebreak_filter', post_process_vlist_nodes, 'luaotfload.harf.finalize_vlist') +add_to_callback('hpack_filter', post_process_nodes, 'luaotfload.harf.finalize_hlist') +add_to_callback('wrapup_run', run_cleanup, 'luaotfload.cleanup_files') +add_to_callback('finish_pdffile', set_tounicode, 'luaotfload.harf.finalize_unicode') +add_to_callback('glyph_info', get_glyph_info, 'luaotfload.glyphinfo') diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua index cfbcb68eab..3b67738fe5 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-init.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua @@ -5,17 +5,13 @@ -- AUTHOR: Philipp Gesang (Phg), , Marcel Krüger ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-init", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end ----------------------------------------------------------------------- @@ -299,7 +295,6 @@ local function init_main(early_hook) local saved_exit = os.exit local errmsg function texio.reporter(msg, ...) - print(...) errmsg = msg end function os.exit() @@ -407,6 +402,11 @@ local function init_main(early_hook) -- fontloader end --- [init_main] +if not luatexbase.callbacktypes.pre_shaping_filter then + luatexbase.create_callback('pre_shaping_filter', 'list') + luatexbase.create_callback('post_shaping_filter', 'reverselist') +end + local init_post_install_callbacks = function () --[[doc-- @@ -423,17 +423,42 @@ local init_post_install_callbacks = function () local fallback = luaotfload.loaders.luaotfload "fallback".process local multiscript = luaotfload.loaders.luaotfload "multiscript".process - -- MK Pass current text direction to simple_font_handler + local call_callback = luatexbase.call_callback + local tex_get = tex.get + local flush_list = node.flush_list local handler = luaotfload.fontloader.nodes.simple_font_handler - local callback = function(head, groupcode, _, _, direction) + local function callback(head, groupcode, _, _, direction) if not direction then - direction = tex.get'textdirection' + direction = tex_get'textdirection' else direction = direction == "TRT" and 1 or 0 end + local result = call_callback("pre_shaping_filter", head, groupcode, direction) + if result == false then + return false + elseif result ~= true then + head = result + end multiscript(head, nil, nil, nil, direction) fallback(head, nil, nil, nil, direction) - return handler(head, groupcode, nil, nil, direction) + result = handler(head, groupcode, nil, nil, direction) + -- handler never returns a boolean and only returns nil if it was passed in + -- We keep it general though for consistency + if result == false then + flush_list(head) + return nil + elseif result ~= true then + head = result + end + result = call_callback("post_shaping_filter", head, groupcode, direction) + if result == false then + flush_list(head) + return nil + elseif result == true then + return head + else + return result + end end luatexbase.add_to_callback("pre_linebreak_filter", callback, @@ -443,7 +468,6 @@ local init_post_install_callbacks = function () callback, "luaotfload.node_processor", 1) - -- /MK local streams = fonts.hashes.streams luatexbase.add_to_callback("glyph_stream_provider",function(id,index,mode) diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf index df1a8e0e86..299ff211aa 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf and b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.tex b/macros/luatex/generic/luaotfload/luaotfload-latex.tex index dcf6507881..40b01af0de 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-latex.tex +++ b/macros/luatex/generic/luaotfload/luaotfload-latex.tex @@ -260,7 +260,7 @@ local stringsub = string.sub local stringgsub = string.gsub %local backslash = unicode.utf8.char (0x200c) - local backslash = unicode.utf8.char (0x5c) + local backslash = string.char(0x5c) local escaped = [[\string\string\string\]] document.printlines = function (buffer) local lines = string.explode (buffer, "\noexpand\n") diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua index f9c24a1335..c1a3d6f1b7 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua @@ -3,20 +3,16 @@ -- DESCRIPTION: part of luaotfload / letterspacing ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-letterspace", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / letterspacing", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang, Ulrike Fischer, Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - --- This code diverged quite a bit from its origin in Context. Please --- do *not* report bugs on the Context list. diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua index a63506237a..84c5555f5d 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua @@ -6,17 +6,13 @@ -- AUTHOR: Hans Hagen, Khaled Hosny, Elie Roux, David Carlisle ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-loaders", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end ----------------------------------------------------------------------- diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua index b102da65bf..58fc403e62 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-log.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua @@ -4,21 +4,16 @@ ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-log", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "Luaotfload Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - --[[doc-- The logging system is slow in general, as we always have the function call overhead even if we aren’t going to output anything. On the other diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.lua b/macros/luatex/generic/luaotfload/luaotfload-main.lua index 5fa8c54ad3..1b029bd514 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-main.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-main.lua @@ -1,341 +1,6 @@ ----------------------------------------------------------------------- -- FILE: luaotfload-main.lua --- DESCRIPTION: OpenType layout system / luaotfload entry point --- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs --- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger +-- DESCRIPTION: OpenType layout system / compatibility wrapper ----------------------------------------------------------------------- -local authors = "\z - Hans Hagen,\z - Khaled Hosny,\z - Elie Roux,\z - Will Robertson,\z - Philipp Gesang,\z - Dohyun Kim,\z - Reuben Thomas,\z - David Carlisle,\ - Ulrike Fischer,\z - Marcel Krüger\z -" --- version number is used below! -local ProvidesLuaModule = { - name = "luaotfload-main", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE - description = "luaotfload entry point", - author = authors, - copyright = authors, - license = "GPL v2.0" -} - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - -local osgettimeofday = os.gettimeofday -config = config or { } -luaotfload = luaotfload or { } -local luaotfload = luaotfload -luaotfload.log = luaotfload.log or { } -local logreport -luaotfload.version = ProvidesLuaModule.version -luaotfload.loaders = { } -luaotfload.fontloader_package = "reference" --- default: from current Context - -if not tex or not tex.luatexversion then - error "this program must be run in TeX mode" --- or call tex.initialize() =) -end - ---- version check -local revno = tonumber(tex.luatexrevision) -local minimum = { 110, 0 } -if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then - texio.write_nl ("term and log", - string.format ("\tFATAL ERROR\n\z - \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z - \tPlease update your TeX distribution!\n\n", - math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2])) - error "version check failed" -end - -if not utf8 then - texio.write_nl("term and log", string.format("\z - \tluaotfload: module utf8 is unavailable\n\z - \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z - \tThis probably means that the engine is not supported\n\z - \n", - _VERSION)) - error "module utf8 is unavailable" -end - -if status.safer_option ~= 0 then - texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting") - error("safer_option used") -end - - - - ---[[doc-- - - This file initializes the system and loads the font loader. To - minimize potential conflicts between other packages and the code - imported from \CONTEXT, several precautions are in order. Some of - the functionality that the font loader expects to be present, like - raw access to callbacks, are assumed to have been disabled by - \identifier{luatexbase} when this file is processed. In some cases - it is possible to trick it by putting dummies into place and - restoring the behavior from \identifier{luatexbase} after - initilization. Other cases such as attribute allocation require - that we hook the functionality from \identifier{luatexbase} into - locations where they normally wouldn’t be. - - Anyways we can import the code base without modifications, which is - due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts - self-contained and encapsulate it, and especially due to his - willingness to incorporate our suggestions. - ---doc]]-- - -local luatexbase = luatexbase -local require = require -local type = type - - ---[[doc-- - - \subsection{Module loading} - We load the files imported from \CONTEXT with function derived this way. It - automatically prepends a prefix to its argument, so we can refer to the - files with their actual \CONTEXT name. - ---doc]]-- - -local function make_loader_name (prefix, name) - local msg = luaotfload.log and luaotfload.log.report - or function (stream, lvl, cat, ...) - if lvl > 1 then --[[not pressing]] return end - texio.write_nl ("log", - string.format ("luaotfload | %s : ", - tostring (cat))) - texio.write (string.format (...)) - end - if not name then - msg ("both", 0, "load", - "Fatal error: make_loader_name (%q, %q).", - tostring (prefix), tostring (name)) - return "dummy-name" - end - name = tostring (name) - if prefix == false then - msg ("log", 9, "load", - "No prefix requested, passing module name %q unmodified.", - name) - return tostring (name) .. ".lua" - end - prefix = tostring (prefix) - msg ("log", 9, "load", - "Composing module name from constituents %s, %s.", - prefix, name) - return prefix .. "-" .. name .. ".lua" -end - -local timing_info = { - t_load = { }, - t_init = { }, -} - -local function make_loader (prefix, load_helper) - return function (name) - local t_0 = osgettimeofday () - local modname = make_loader_name (prefix, name) - --- We don’t want the stack info from inside, so just pcall(). - local ok, data = pcall (load_helper or require, modname) - local t_end = osgettimeofday () - timing_info.t_load [name] = t_end - t_0 - if not ok then - io.write "\n" - local msg = luaotfload.log and luaotfload.log.report or print - msg ("both", 0, "load", "FATAL ERROR") - msg ("both", 0, "load", " × Failed to load %q module %q.", - tostring (prefix), tostring (name)) - local lines = string.split (data, "\n\t") - if not lines then - msg ("both", 0, "load", " × Error message: %q", data) - else - msg ("both", 0, "load", " × Error message:") - for i = 1, #lines do - msg ("both", 0, "load", " × %q.", lines [i]) - end - end - io.write "\n\n" - local debug = debug - if debug then - io.write (debug.traceback()) - io.write "\n\n" - end - os.exit(-1) - end - return data - end -end - ---[[doc-- - Certain files are kept around that aren’t loaded because they are part of - the imported fontloader. In order to keep the initialization structure - intact we also provide a no-op version of the module loader that can be - called in the expected places. ---doc]]-- - -local function dummy_loader (name) - luaotfload.log.report ("log", 3, "load", - "Skipping module %q on purpose.", - name) -end - -local context_environment = setmetatable({}, {__index = _G}) -luaotfload.fontloader = context_environment -local function context_isolated_load(name) - local fullname = kpse.find_file(name, 'lua') - if not fullname then - error(string.format('Fontloader module %q could not be found.', name)) - end - return assert(loadfile(fullname, nil, context_environment))(name) -end - -local function context_loader (name, path) - luaotfload.log.report ("log", 3, "load", - "Loading module %q from Context.", - name) - local t_0 = osgettimeofday () - local modname = make_loader_name (false, name) - local modpath = modname - if path then - if lfs.isdir (path) then - luaotfload.log.report ("log", 3, "load", - "Prepending path %q.", - path) - modpath = file.join (path, modname) - else - luaotfload.log.report ("both", 0, "load", - "Non-existant path %q specified, ignoring.", - path) - end - end - local ret = context_isolated_load (modpath) - local t_end = osgettimeofday () - timing_info.t_load [name] = t_end - t_0 - - if ret ~= nil then - --- require () returns “true” upon success unless the loaded file - --- yields a non-zero exit code. This isn’t per se indicating that - --- something isn’t right, but against HH’s coding practices. We’ll - --- silently ignore this ever happening on lower log levels. - luaotfload.log.report ("log", 4, "load", - "Module %q returned %q.", modname, ret) - end - return ret -end - -local function install_loaders () - local loaders = { } - local loadmodule = make_loader "luaotfload" - loaders.luaotfload = loadmodule - loaders.fontloader = make_loader ("fontloader", context_isolated_load) - loaders.context = context_loader - loaders.ignore = dummy_loader -----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain - - function loaders.initialize (name) - local tmp = loadmodule (name) - local init = type(tmp) == "table" and tmp.init or tmp - if init and type (init) == "function" then - local t_0 = osgettimeofday () - if not init () then - logreport ("log", 0, "load", - "Failed to load module %q.", name) - return - end - local t_end = osgettimeofday () - local d_t = t_end - t_0 - logreport ("log", 4, "load", - "Module %q loaded in %g ms.", - name, d_t * 1000) - timing_info.t_init [name] = d_t - end - end - - return loaders -end - -local luaotfload_initialized = false --- prevent multiple invocations - -luaotfload.main = function () - - if luaotfload_initialized then - logreport ("log", 0, "load", - "Luaotfload initialization requested but is already \z - loaded, ignoring.") - return - end - luaotfload_initialized = true - - luaotfload.loaders = install_loaders () - local loaders = luaotfload.loaders - local loadmodule = loaders.luaotfload - local initialize = loaders.initialize - - local starttime = osgettimeofday () - - -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz - -- detection in other modules - local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') - if harfstatus then - luaotfload.harfbuzz = harfbuzz - end - - local init = loadmodule "init" --- fontloader initialization - init (function () - - logreport = luaotfload.log.report - initialize "parsers" --- fonts.conf and syntax - initialize "configuration" --- configuration options - end) - - initialize "loaders" --- Font loading; callbacks - initialize "database" --- Font management. - initialize "colors" --- Per-font colors. - - local init_resolvers = loadmodule "resolvers" --- Font lookup - init_resolvers () - - if not config.actions.reconfigure () then - logreport ("log", 0, "load", "Post-configuration hooks failed.") - end - - initialize "features" --- font request and feature handling - - if harfstatus then - loadmodule "harf-define" - loadmodule "harf-plug" - end - loadmodule "letterspace" --- extra character kerning - loadmodule "embolden" --- fake bold - loadmodule "notdef" --- missing glyph handling - loadmodule "suppress" --- suppress ligatures by adding ZWNJ - loadmodule "szss" --- missing glyph handling - initialize "auxiliary" --- additional high-level functionality - loadmodule "tounicode" - if tex.outputmode == 0 then - loadmodule "dvi" --- allow writing fonts to DVI files - end - - luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec - - logreport ("log", 1, "main", - "initialization completed in %0.3f seconds\n", - osgettimeofday() - starttime) -----inspect (timing_info) -end - --- vim:tw=79:sw=4:ts=4:et +return require'luaotfload' diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex index a1f79b7da4..d1f698f684 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-main.tex +++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex @@ -32,7 +32,7 @@ \beginfrontmatter \setdocumenttitle {The \identifier{luaotfload} package} - \setdocumentdate {2020-09-02 v3.15} + \setdocumentdate {2020-12-31 v3.16} \setdocumentauthor {LaTeX3 Project\\ Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\ Home: \hyperlink {https://github.com/latex3/luaotfload}} @@ -62,6 +62,30 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c \endsection \beginsection{Changes} +\beginsubsection {New in version 3.16 (by Ulrike Fischer/Marcel Krüger)} +\begin{itemize} + \item The entry point is called \identifier{luaotfload.lua} instead of + \identifier{luaotfload-main.lua} (but the old name is still provided for compatibility). + \item \inlinecode{pre/post_shaping_filter} callbacks has been added. + \item The number of \abbrev{lua}-files and submodules shown in the \abbrev{log}-file has been reduced. But it + is extended again by setting the environment variable \inlinecode{LUAOTFLOAD_TRACE_SUBMODULES=1}. + \item The HarfBuzz based shaper will in some situations drop hyphenation + points. This happens less frequently now since the new version uses + first/second discretionaries (the mechanism described in the LuaTeX manual, + section 5.6 for the of-f-ice example) to support a limited amount of + nesting. + \item When the \texttt{node} shaper is used, experimental support for OpenType variable + fonts has been added. To use them, set the font feature \texttt{axis} to + a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}}) + The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}). + \item The font features \texttt{upper} and \texttt{lower} can be used to map + the text of a font to upper or lowercase before displaying it. Currently + this implements the untailored Unicode case mapping algorithm, but it is + planned to add tailoring later (see~page~\pageref{upperlower}). + \item A number of small bugfixes. + \end{itemize} +\endsubsection + \beginsubsection {New in version 3.15 (by Ulrike Fischer/Marcel Krüger)} \begin{itemize} \item The font database is updated more reliably if fonts get deleted. @@ -1166,8 +1190,8 @@ obviously, \inlinecode{random}. \endaltitem - \beginaltitem {multiscript}\phantomsection\label{multiscript} - In\marginpar{New in 3.12 -- experimental} fonts many shaping rules are implemented only for specific scripts and so you get correct typesetting only if the \identifier{script} feature is correctly set. This means that to write a text which uses more than one script you have to declare a font for each script and switch fonts even if the font contains glyphs for all scripts. + \beginaltitem {multiscript} + In\phantomsection\label{multiscript}\marginpar{New in 3.12 -- experimental} fonts many shaping rules are implemented only for specific scripts and so you get correct typesetting only if the \identifier{script} feature is correctly set. This means that to write a text which uses more than one script you have to declare a font for each script and switch fonts even if the font contains glyphs for all scripts. \identifier{multiscript} tries to help here. The feature is experimental and bound to change. Feedback is welcome but you use it at your risk. \identifier{multiscript} allows you to declare fonts for various script. The value is either \identifier{auto} described below, or a name which has been previously declared or a combination of both. An example for such a named multiscript could look like this (the colors are only for demonstration): @@ -1221,8 +1245,10 @@ obviously, \inlinecode{random}. \endaltitem - \beginaltitem {fallback}\label{fallback} - This\marginpar{New in 3.12 -- experimental} allows you to define a chain of fonts which are used if glyphs are missing in the main font. It works only for text fonts, not for math fonts set with the \identifier{unicode-math} package. + \beginaltitem {fallback} + This\label{fallback}\marginpar{New in 3.12 -- experimental} + allows you to define a chain of fonts which are used if glyphs are missing in the main font. + It works only for text fonts, not for math fonts set with the \identifier{unicode-math} package. The feature is experimental and bound to change. Feedback is welcome but you use it at your risk. For example @@ -1276,7 +1302,69 @@ obviously, \inlinecode{random}. As with the \identifier{multiscript} key more control over the used glyph and script in edge cases will be needed. \endaltitem -\enddescriptions + + \beginaltitem {upper/lower} + The\phantomsection\label{upperlower}\marginpar{New in 3.16} + font features \texttt{upper} and \texttt{lower} can be used to map + the text of a font to upper or lowercase before displaying it. Currently + this implements the untailored Unicode case mapping algorithm, but it is + planned to add tailoring later. For example + + \beginlisting + \font\test={name:LatinModernRoman:mode=node;+upper;} + \test Grüße + \endlisting + + {\Large\font\test={name:LatinModernRoman:mode=node;+upper;}\test Grüße} + + \endaltitem + + \beginaltitem {Variable fonts} + When\phantomsection\label{variablefonts}\marginpar{New in 3.16} + the \texttt{node} shaper is used, + experimental support for OpenType variable + fonts has been added. To use them, set the font feature \texttt{axis} to + a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}}) + The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}). + The following listing shows an example with the Source Code Variable font: + + \begin{lstlisting}[columns=fullflexible] +\documentclass{article} + \DeclareFontFamily{TU}{sourcecode-variable}{} + \newcommand\DeclareSourceVariable[2]{% + \DeclareFontShape{TU}{sourcecode-variable}{#1}{n}{% + <-> \UnicodeFontFile{SourceCodeVariable-Roman.otf} + {\UnicodeFontTeXLigatures axis={weight=#2};}% + }{}% + \DeclareFontShape{TU}{sourcecode-variable}{#1}{it}{% + <-> \UnicodeFontFile{SourceCodeVariable-Italic.otf} + {\UnicodeFontTeXLigatures axis={weight=#2};}% + }{}% + } + \DeclareSourceVariable{ul}{200} + \DeclareSourceVariable{el}{250} + \DeclareSourceVariable{l}{300} + \DeclareSourceVariable{sl}{350} + \DeclareSourceVariable{m}{400} + \DeclareSourceVariable{sb}{500} + \DeclareSourceVariable{b}{600} + \DeclareSourceVariable{eb}{700} + \DeclareSourceVariable{ub}{900} + \begin{document} + \fontfamily{sourcecode-variable}\selectfont + \fontseries{ul}\selectfont a\textit{b} + \fontseries{el}\selectfont c\textit{d} + \fontseries{l}\selectfont e\textit{f} + \fontseries{sl}\selectfont g\textit{h} + \fontseries{m}\selectfont i\textit{j} + \fontseries{sb}\selectfont k\textit{l} + \fontseries{b}\selectfont m\textit{n} + \fontseries{eb}\selectfont o\textit{p} + \fontseries{ub}\selectfont q\textit{r} + \end{document} +\end{lstlisting} + + \enddescriptions \endsubsection @@ -1339,6 +1427,7 @@ Currently (2014) there are three of them: \enddescriptions \endsubsection + \endsection %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua index aae924c9de..a632ab4c6a 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / multiscript ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-multiscript", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local nodenew = node.direct.new local getfont = font.getfont local setfont = node.direct.setfont diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua index f2043a7ad7..7b9664fa7e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / notdef ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-notdef", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / notdef", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local harfbuzz = luaotfload.harfbuzz local flush_node = node.direct.flush_node local getfont = font.getfont diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua index f321e9733f..7810c3a49e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua @@ -5,19 +5,14 @@ -- AUTHOR: Philipp Gesang (Phg), , Marcel Krüger ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-parsers", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / parsers", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - local traversal_maxdepth = 42 --- prevent stack overflows local rawset = rawset diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua index b7ca21ec87..2ea85de781 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua @@ -9,19 +9,14 @@ --- The bare fontloader uses a set of simplistic file name resolvers --- that must be overloaded by the user (i. e. us). -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-resolvers", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - if not lualibs then error "this module requires Luaotfload" end if not luaotfload then error "this module requires Luaotfload" end diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua index 6ac19f14d5..b6c34b9e3e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / script ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-script", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Script helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local canonical_name = { dflt = "DFLT", hira = "kana", diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua index dd38631cc8..0ad3c01ead 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-status.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua @@ -1,97 +1,99 @@ return { ["hashes"]={ - { "fontloader-2020-08-31.lua", "70a72561e3869bcaa8554921083b3872" }, - { "fontloader-util-fil.lua", "aae2a2add764144bb58dd8216fd59260" }, - { "fontloader-util-str.lua", "c975ff7bbd178163cf47d9e9296c8b4b" }, - { "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" }, - { "fontloader-l-math.lua", "082add08e0bb79f39191ae9534a79849" }, - { "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" }, - { "fontloader-l-file.lua", "352b42b8360ada02ceb26a41f0bd2a76" }, - { "fontloader-l-io.lua", "bbcc4824d0ded30b415d7d2d5763028a" }, - { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" }, - { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" }, - { "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" }, - { "fontloader-l-lpeg.lua", "10bdaef44175902917691835010ae5f5" }, - { "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" }, - { "fontloader-fonts-gbn.lua", "10ecdf01e7c926e5128ad8a9dff4d677" }, - { "fontloader-fonts-lig.lua", "fbd251eea3810a43a8d5542319361d68" }, - { "fontloader-fonts-ext.lua", "32013cbc5d5d336be8b1d1e5879d86c4" }, - { "fontloader-fonts-def.lua", "f435e0875f203f343157baeff876ec9c" }, - { "fontloader-fonts-tfm.lua", "f0eb5e2a8068b17ad401bb7efdba1630" }, - { "fontloader-fonts-enc.lua", "5ff4ca50493d7c4ecea0e15c203099f0" }, - { "fontloader-fonts-mis.lua", "17e967c9ec4d001deefd43ddf25e98f7" }, - { "fontloader-basics-chr.lua", "64fafe4eaf55d64aead6513c1e74a024" }, - { "fontloader-basics-nod.lua", "335e61ffb6dec00f88f737854a2d9ab4" }, - { "fontloader-font-imp-effects.lua", "d9b935e9b73f250a175ddd71a226b8e9" }, - { "fontloader-font-imp-italics.lua", "ae563638fa29a4ff3e8e4d1e81fd35ae" }, - { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" }, - { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" }, - { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" }, - { "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" }, - { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" }, - { "fontloader-font-one.lua", "5a2f244c88c8178e997c16a9b628bb6f" }, - { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" }, - { "fontloader-font-otc.lua", "0f12230ea07b5151f75d52726977e91f" }, - { "fontloader-font-ocl.lua", "797b5c71bf819c5f4fb314a4d646e9a7" }, - { "fontloader-font-osd.lua", "73c9531c79df5ada320cb20777f7ed49" }, - { "fontloader-font-ots.lua", "f018ae1f355a8ef5c8d403cc5489e3d3" }, - { "fontloader-font-ota.lua", "ad1d5de06400f88829509e1f3ff2b473" }, - { "fontloader-font-otj.lua", "8de59cb9b043e5f73c6b9f7cc8f6978e" }, - { "fontloader-font-oto.lua", "2b1d6bc63b2ebf8f2655a15e1cda6541" }, - { "fontloader-font-otl.lua", "b168cf69300873d6668203bc7afe1f56" }, - { "fontloader-font-oup.lua", "6f46aa00ae1c20c43f8ffaf329dc8695" }, - { "fontloader-font-dsp.lua", "5d6528c0673b7651600ca6b763b51df5" }, - { "fontloader-font-ttf.lua", "786a535ba0385446b7015260388bc415" }, - { "fontloader-font-cff.lua", "802a10ad12ac32329f540881f940e3f2" }, - { "fontloader-font-ott.lua", "673ed11e1d159997f535bfec5fa73808" }, - { "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" }, - { "fontloader-font-otr.lua", "64dcbbc7107538723990e1119a80a9f8" }, - { "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" }, - { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" }, - { "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" }, - { "fontloader-font-con.lua", "a3eb543fa5946fa1faf0e1e50d5b3b91" }, - { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" }, - { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" }, - { "fontloader-reference.lua", "c10086745bc0b8b2303572fdea86d61c" }, - { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" }, - { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" }, - { "mkstatus", "49692433db8a578cf3a03fbedfb2ea9c" }, - { "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" }, - { "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" }, - { "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" }, - { "luaotfload-glyphlist.lua", "af60521c7ea3f5828c83ed1d1fa23b45" }, - { "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" }, - { "luaotfload-tounicode.lua", "24601f0255c35508eddbb427a6e18873" }, - { "luaotfload-unicode.lua", "c7d3f282db7a0f9588cc57d8f079a3cb" }, - { "luaotfload-resolvers.lua", "ac9e134e0614ab7ab69122ec0fd99e54" }, - { "luaotfload-parsers.lua", "10afafb81544840cb0fd0ecaac3c3344" }, - { "luaotfload-fallback.lua", "9d70a346c2584834f40d83be25d53a6a" }, - { "luaotfload-szss.lua", "0e29a05f35bbd05388e5af674059c242" }, - { "luaotfload-scripts.lua", "9a1e50e55ddef481ca3863004f33703e" }, - { "luaotfload-multiscript.lua", "8a828bf429dc73742ea78ad73332d219" }, - { "luaotfload-loaders.lua", "f13bafee1dca48db5073fe4390dc8ec4" }, - { "luaotfload-harf-plug.lua", "f43e0d894cf9ca3f31ff405d1684a5ff" }, - { "luaotfload-harf-define.lua", "0aecef4ea82a6edc305be2eed7b8e9c9" }, - { "luaotfload-notdef.lua", "73762a6d7662aa090f8f950a34d55835" }, - { "luaotfload-embolden.lua", "3444350537a12803b8e255f56b33b50d" }, - { "luaotfload-letterspace.lua", "6ac6c8d6f54107984ad338a94f0acd86" }, - { "luaotfload-features.lua", "b42fbc57c4fb1306dc23bf4e3bf6cd98" }, - { "luaotfload-database.lua", "8e11e69cf6a83bc1723c95e4788cdc70" }, - { "luaotfload-configuration.lua", "d1f4d64caa58bfc5feb524ea7cd365f6" }, - { "luaotfload-colors.lua", "5d1e7e10b5a8dda7ccf3742ae90f002e" }, - { "luaotfload-auxiliary.lua", "6d4e31212b8852e5f1425dc0ea49e016" }, - { "luaotfload-filelist.lua", "5e4c15ea6e5aafc19a533289b6ac2709" }, - { "luaotfload-tool.lua", "9caf618c38bf58cf9a29f2b2d4449346" }, - { "luaotfload-diagnostics.lua", "797176921da30591e6112831ed7459a7" }, - { "luaotfload-log.lua", "932117045a6abfe303314a295c24d338" }, - { "luaotfload-init.lua", "eb1bfca3833688aba31521032ed38883" }, - { "luaotfload-main.lua", "133ee97a73e07f3116d0417c9373398b" }, + { "fontloader-2020-12-30.lua", "68ad807e7fdc2161801a16d1d404e1c4" }, + { "fontloader-util-fil.lua", "a617cad49fc028e99f0f30bce8b2b623" }, + { "fontloader-util-str.lua", "a2041dad54b982ad124cbc764f5de43b" }, + { "fontloader-l-unicode.lua", "a4464b61c123f0454bea92c1cf502891" }, + { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" }, + { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" }, + { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" }, + { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" }, + { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" }, + { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, + { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, + { "fontloader-l-lpeg.lua", "c3407de16bcedd73652250b000b39e98" }, + { "fontloader-l-lua.lua", "c8dbb33df962e1b945b91b906b3c15c4" }, + { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, + { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, + { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, + { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" }, + { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" }, + { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, + { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, + { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, + { "fontloader-basics-nod.lua", "6549c88db8cf4c6ae005a2e08f223d4b" }, + { "fontloader-font-imp-effects.lua", "231cda056b88f6dc282fab9d7643d380" }, + { "fontloader-font-imp-italics.lua", "058fb834c11c6ac30c280b29e496966e" }, + { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, + { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" }, + { "fontloader-font-shp.lua", "72de6029980ac796ec6ec76fa3ec8684" }, + { "fontloader-font-def.lua", "226b4d26ede7fa7be8e45b7f0d93e781" }, + { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" }, + { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, + { "fontloader-font-one.lua", "2e52d1e42764f68b779522bda9569480" }, + { "fontloader-font-onr.lua", "7a9ece7bf3e36b5f0adf295a9a2a2989" }, + { "fontloader-font-ocl.lua", "ab81576f20e2d37bc8707e1dbd3decf2" }, + { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" }, + { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, + { "fontloader-font-ots.lua", "a83d5992a82b706c0ffdb5c2778534f1" }, + { "fontloader-font-ota.lua", "f31232af3a694ae3d50380a5a92f88d3" }, + { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" }, + { "fontloader-font-otj.lua", "a37a1007b8a92c9e7d24064180c2a772" }, + { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" }, + { "fontloader-font-otl.lua", "70237f19b76c4bc75f0c6e89038fb49a" }, + { "fontloader-font-ott.lua", "1249b7018dba80e080fc478a38aa6756" }, + { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" }, + { "fontloader-font-dsp.lua", "10eb256f4bcb9c5eabd48048e2da5eab" }, + { "fontloader-font-ttf.lua", "ebef049a169c04edd19902fd66ddea44" }, + { "fontloader-font-cff.lua", "aa9038651d9fedd2b76cacd1f69fd742" }, + { "fontloader-font-otr.lua", "7a2f7a9e9627b29158e1822ea3c650ab" }, + { "fontloader-font-vfc.lua", "04fa0ffad5c51198c7c19462949f54ed" }, + { "fontloader-font-map.lua", "a03653ea3c5f042b457d54ed678d6df3" }, + { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, + { "fontloader-font-con.lua", "cbccccc4a5016196d62332a365aa8b72" }, + { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" }, + { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" }, + { "fontloader-reference.lua", "957f358a48ea6fcbc78a8701f947d7e5" }, + { "fontloader-basics-gen.lua", "7bcfb5e4f48a1a34be6ddfcee2b1e49d" }, + { "mktests", "c7cff7025962922944376acc1ffa9c47" }, + { "mkstatus", "f3b00b5999440afce64bdc448f3fda9a" }, + { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, + { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" }, + { "mkimport", "5dacc09f3358ba9b90cf3a804f9a535c" }, + { "luaotfload-glyphlist.lua", "bb6a9912a0944b3b21a61fce247dd728" }, + { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" }, + { "luaotfload-dvi.lua", "34e1550905555da63304e07797168c69" }, + { "luaotfload-tounicode.lua", "09fa475eeb7b160d3eb124e9107d4e03" }, + { "luaotfload-unicode.lua", "153f97b086fd38dcb7f4850d95a41016" }, + { "luaotfload-resolvers.lua", "2441b9624775fbcea6617e6cc72b424d" }, + { "luaotfload-parsers.lua", "623d33f43813eda562cbfef5528753de" }, + { "luaotfload-fallback.lua", "ec702c1c9407eba7bfe80b59c36f3f67" }, + { "luaotfload-szss.lua", "ee4c0c070dcacf4d3e43f52948611392" }, + { "luaotfload-scripts.lua", "14a19085cd5288592ebd5e24acf8514a" }, + { "luaotfload-multiscript.lua", "4a283df608be713b0b666515fb6b9789" }, + { "luaotfload-loaders.lua", "f0eeb293d8f448413631b1ffff554e39" }, + { "luaotfload-harf-plug.lua", "34182344e7985d1267dacde37f387433" }, + { "luaotfload-harf-define.lua", "252c36178f4f9ab066bdc15adfe809f1" }, + { "luaotfload-notdef.lua", "06278786a6f2f8ddd3749b5d75f611db" }, + { "luaotfload-embolden.lua", "8bdfebc528d078086c7fd0747815df74" }, + { "luaotfload-letterspace.lua", "57d6026196fa62f9891d7a7a7300f63f" }, + { "luaotfload-features.lua", "2219adcecef7362bbbe46da2e5ed005b" }, + { "luaotfload-database.lua", "e2bea14191641d3a18b04064752d0fd4" }, + { "luaotfload-configuration.lua", "dfa0521ef327c68573ea587ed7b989c8" }, + { "luaotfload-colors.lua", "32bf6714aa19f6c291922cd1be01b629" }, + { "luaotfload-auxiliary.lua", "4c18ffcc0d1cbef3ad4db2b6440a863e" }, + { "luaotfload-filelist.lua", "8bb0a321254e6f04a1fa776d2f67747f" }, + { "luaotfload-tool.lua", "ac7b0adfd9d0096228bed8ae61540a70" }, + { "luaotfload-diagnostics.lua", "21bca70ad0b6f7dd1d9d57c7b1513809" }, + { "luaotfload-log.lua", "d9c45eff233d71c3824f3a579694d737" }, + { "luaotfload-init.lua", "265f1bfe8789fbb0cc3bff3a780f5494" }, + { "luaotfload-main.lua", "f5f771d1cf5c8c4a2519a8d46aed1241" }, }, ["notes"]={ - ["committer"]="Marcel Fabian Krüger ", - ["description"]="v3.15/2020-09-02", - ["loader"]="fontloader-2020-08-31.lua", - ["revision"]="77eede02640bef0cb596d24aa79661328a68b448", - ["timestamp"]="2020-09-02 21:02:40 +0200", + ["committer"]="Ulrike Fischer ", + ["description"]="v3.16/2020-12-31", + ["loader"]="fontloader-2020-12-30.lua", + ["revision"]="d1423b56efe2649e2881657747cee8d54cf64e12", + ["timestamp"]="2020-12-31 12:35:44 +0100", }, } \ No newline at end of file diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua index 768cf81402..c4c0c1010e 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / suppress ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-suppress", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / suppress", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local direct = node.direct local otfregister = fonts.constructors.features.otf.register diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua index 751964cdd1..4c7de4d11b 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / szss ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-szss", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Special feature handling", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local direct = node.direct local otfregister = fonts.constructors.features.otf.register diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1 index ea2d12e9eb..7cd4934ab0 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.1 +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD-TOOL 1 "2020-09-02" "3.15" "text processing" +.TH LUAOTFLOAD-TOOL 1 "2020-12-31" "3.16" "text processing" .SH NAME luaotfload-tool \- generate and query the Luaotfload font names database . @@ -327,7 +327,7 @@ state. .SS miscellaneous .INDENT 0.0 .TP -.BI \-\-verbose\fB= N\fP,\fB \ \-v +.BI \-\-verbose\fB= N\fR,\fB \ \-v Set verbosity level to \fIn\fP or the number of repetitions of \fB\-v\fP\&. .TP diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua index 18334d5ab3..fd66a9f79c 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua @@ -9,15 +9,13 @@ local ProvidesLuaModule = { name = "luaotfload-tool", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload-tool / database functionality", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end +function luaotfload_module(module) end -- We don't log module loading here luaotfload = luaotfload or { } @@ -70,7 +68,7 @@ do local revn = tonumber (status.luatex_revision) or 0 --[[ : string ]] if status.luatex_version < minimum[1] - or status.luatex_version == minimum[1] and status.luatex_revision < minimum[2] then + or status.luatex_version == minimum[1] and tonumber(status.luatex_revision) < minimum[2] then texio.write_nl ("term and log", string.format ("\tFATAL ERROR\n\z \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf index 6697476a0e..e35752ab17 100644 Binary files a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf and b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf differ diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst index c030ab81f2..c4c15d916f 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tool.rst +++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst @@ -6,9 +6,9 @@ generate and query the Luaotfload font names database ----------------------------------------------------------------------- -:Date: 2020-09-02 +:Date: 2020-12-31 :Copyright: GPL v2.0 -:Version: 3.15 +:Version: 3.16 :Manual section: 1 :Manual group: text processing diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua index 028aef9d12..f4eeec1125 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua @@ -3,20 +3,16 @@ -- DESCRIPTION: part of luaotfload / tounicode overwrites ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-tounicode", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / tounicode", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", copyright = "PRAGMA ADE / ConTeXt Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local overloads = { -- rougly based on texglyphlist-g2u.txt diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua index 2e9b28cf79..a05c660a36 100644 --- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua +++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / unicode ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-unicode", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Unicode helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local utf8codes = utf8.codes local utf8char = utf8.char local sub = string.sub @@ -103,7 +99,149 @@ local alphnum_only do end end +local uppercase, lowercase, ccc, cased, case_ignorable, titlecase = {}, {}, {}, {}, {}, nil do + titlecase = nil -- Not implemented yet(?) + local ignored_field = (1-lpeg.P';')^0 * ';' + local cased_category = lpeg.P'Ll;' + 'Lu;' + 'Lt;' + local case_ignore_category = lpeg.P'Mn;' + 'Me;' + 'Cf;' + 'Lm;' + 'Sk;' + + local simple_entry = + codepoint/0 * ';' + * ignored_field -- Name + * (ignored_field - cased_category - case_ignore_category) -- General_Category + * '0;' -- ccc + * ignored_field -- Bidi + * ignored_field -- Decomp + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Mirrored + * ignored_field -- Obsolete + * ignored_field -- Obsolete + * ';;\n' + local entry = simple_entry + + codepoint * ';' + * ignored_field -- Name + * (cased_category * lpeg.Cc(cased) + case_ignore_category * lpeg.Cc(case_ignorable) + ignored_field * lpeg.Cc(nil)) -- General_Category + * ('0;' * lpeg.Cc(nil) + lpeg.R'09'^1/tonumber * ';') -- ccc + * ignored_field -- Bidi + * ignored_field -- Decomp + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Mirrored + * ignored_field -- Obsolete + * ignored_field -- Obsolete + * (codepoint + lpeg.Cc(nil)) * ';' -- uppercase + * (codepoint + lpeg.Cc(nil)) * ';' -- lowercase + * (codepoint + lpeg.Cc(nil)) * '\n' -- titlecase + / function(codepoint, cased_flag, ccc_val, upper, lower, title) + if cased_flag then cased_flag[codepoint] = true end + ccc[codepoint] = ccc_val + uppercase[codepoint] = upper + lowercase[codepoint] = lower + -- if title then titlecase[codepoint] = title end -- Not implemented yet(?) + end + local file = entry^0 * -1 + + local f = io.open(kpse.find_file"UnicodeData.txt") + assert(file:match(f:read'*a')) + f:close() +end + +local props do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local entry = codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * lpeg.C(lpeg.R("AZ", "az", "__")^1) * nl + local file = lpeg.Cf( + lpeg.Ct( + lpeg.Cg(lpeg.Ct"", "Soft_Dotted") + * lpeg.Cg(lpeg.Cc(cased), "Other_Lowercase") + * lpeg.Cg(lpeg.Cc(cased), "Other_Uppercase")) + * (lpeg.Cg(entry) + nl)^0 + , function(t, cp_start, cp_end, prop) + local prop_table = t[prop] + if prop_table then + for cp = cp_start, cp_end or cp_start do + prop_table[cp] = true + end + end + return t + end) * -1 + + local f = io.open(kpse.find_file"PropList.txt") + props = file:match(f:read'*a') + f:close() +end + +do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local file = (codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * (lpeg.P'Single_Quote' + 'MidLetter' + 'MidNumLet') * nl / function(cp_start, cp_end) + for cp = cp_start, cp_end or cp_start do + case_ignorable[cp] = true + end + end + (1-lpeg.P'\n')^0 * '\n')^0 * -1 + + local f = io.open(kpse.find_file"WordBreakProperty.txt") + assert(file:match(f:read'*a')) + f:close() +end + +do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local empty = {} + local function set(t, cp, condition, value) + local old = t[cp] or cp + if not condition then + if #value == 1 and tonumber(old) then + t[cp] = value[1] + return + end + condition = empty + end + if tonumber(old or cp) then + old = {_ = {old}} + t[cp] = old + end + for i=1, #condition do + local cond = condition[i] + local step = old[cond] + if not step then + step = {} + old[cond] = step + end + old = step + end + old._ = value + end + local entry = codepoint * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * (lpeg.Ct((ws * lpeg.C(lpeg.R('AZ', 'az', '__')^1))^1) * ";")^-1 + * ws * nl / function(cp, lower, title, upper, condition) + set(lowercase, cp, condition, lower) + set(uppercase, cp, condition, upper) + end + local file = (entry + nl)^0 * -1 + + local f = io.open(kpse.find_file"SpecialCasing.txt") + assert(file:match(f:read'*a')) + f:close() +end + return { casefold = casefold, alphnum_only = alphnum_only, + casemapping = { + uppercase = uppercase, + lowercase = lowercase, + cased = cased, + case_ignorable = case_ignorable, + -- titlecase = titlecase, + }, + ccc = ccc, + soft_dotted = props.Soft_Dotted, } diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5 index 0035ce834f..4620ef0f2f 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.conf.5 +++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH LUAOTFLOAD.CONF 5 "2020-09-02" "3.15" "text processing" +.TH LUAOTFLOAD.CONF 5 "2020-12-31" "3.16" "text processing" .SH NAME luaotfload.conf \- Luaotfload configuration file . diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst index d40cb3a967..5905eb3811 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.conf.rst +++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst @@ -6,9 +6,9 @@ Luaotfload configuration file ----------------------------------------------------------------------- -:Date: 2020-09-02 +:Date: 2020-12-31 :Copyright: GPL v2.0 -:Version: 3.15 +:Version: 3.16 :Manual section: 5 :Manual group: text processing diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua new file mode 100644 index 0000000000..843c84a3bf --- /dev/null +++ b/macros/luatex/generic/luaotfload/luaotfload.lua @@ -0,0 +1,375 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload.lua +-- DESCRIPTION: OpenType layout system / luaotfload entry point +-- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs +-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger +----------------------------------------------------------------------- + +local authors = "\z + Hans Hagen,\z + Khaled Hosny,\z + Elie Roux,\z + Will Robertson,\z + Philipp Gesang,\z + Dohyun Kim,\z + Reuben Thomas,\z + David Carlisle,\ + Ulrike Fischer,\z + Marcel Krüger\z +" +-- version number is used below! +local ProvidesLuaModule = { + name = "luaotfload", + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE + description = "Lua based OpenType font support", + author = authors, + copyright = authors, + license = "GPL v2.0" +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +if luaotfload_module == nil then + local print_warning = luatexbase and luatexbase.module_warning or function(module, text) + return texio.write_nl("%s WARNING: %s", module, text) + end + local saved_version = ProvidesLuaModule.version + local trace_submodules = tonumber(os.getenv'LUAOTFLOAD_TRACE_SUBMODULES') + if luatexbase and luatexbase.provides_module and trace_submodules and trace_submodules ~= 0 then + luaotfload_module = luatexbase.provides_module + else + function luaotfload_module(module) + local module_version = module.version + if module_version ~= saved_version then + local filenames + if debug then + filenames = string.format("luaotfload.lua is found at\n%q\n%s.lua is found at\n%q\n", + debug.getinfo(1, "S").source:sub(2), + module.name, + debug.getinfo(2, "S").source:sub(2)) + else + filenames = "" + end + print_warning("luaotfload", string.format("Version inconsistency detected.\n\z + luaotfload is loaded in version %s, while %q is loaded \z + in version %s.\n%sI will try to continue anyway.\nHIC SUNT DRACONES", + saved_version, module.name, module_version, filenames)) + end + end + end +else + error[[luaotfload is reloading itself nested. This can't happen.]] +end + +local osgettimeofday = os.gettimeofday +config = config or { } +luaotfload = luaotfload or { } +local luaotfload = luaotfload +luaotfload.log = luaotfload.log or { } +local logreport +luaotfload.version = ProvidesLuaModule.version +luaotfload.loaders = { } +luaotfload.fontloader_package = "reference" --- default: from current Context + +if not tex or not tex.luatexversion then + error "this program must be run in TeX mode" --- or call tex.initialize() =) +end + +--- version check +local revno = tonumber(tex.luatexrevision) +local minimum = { 110, 0 } +if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then + texio.write_nl ("term and log", + string.format ("\tFATAL ERROR\n\z + \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z + \tPlease update your TeX distribution!\n\n", + math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2])) + error "version check failed" +end + +if not utf8 then + texio.write_nl("term and log", string.format("\z + \tluaotfload: module utf8 is unavailable\n\z + \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z + \tThis probably means that the engine is not supported\n\z + \n", + _VERSION)) + error "module utf8 is unavailable" +end + +if status.safer_option ~= 0 then + texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting") + error("safer_option used") +end + + + + +--[[doc-- + + This file initializes the system and loads the font loader. To + minimize potential conflicts between other packages and the code + imported from \CONTEXT, several precautions are in order. Some of + the functionality that the font loader expects to be present, like + raw access to callbacks, are assumed to have been disabled by + \identifier{luatexbase} when this file is processed. In some cases + it is possible to trick it by putting dummies into place and + restoring the behavior from \identifier{luatexbase} after + initilization. Other cases such as attribute allocation require + that we hook the functionality from \identifier{luatexbase} into + locations where they normally wouldn’t be. + + Anyways we can import the code base without modifications, which is + due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts + self-contained and encapsulate it, and especially due to his + willingness to incorporate our suggestions. + +--doc]]-- + +local luatexbase = luatexbase +local require = require +local type = type + + +--[[doc-- + + \subsection{Module loading} + We load the files imported from \CONTEXT with function derived this way. It + automatically prepends a prefix to its argument, so we can refer to the + files with their actual \CONTEXT name. + +--doc]]-- + +local function make_loader_name (prefix, name) + local msg = luaotfload.log and luaotfload.log.report + or function (stream, lvl, cat, ...) + if lvl > 1 then --[[not pressing]] return end + texio.write_nl ("log", + string.format ("luaotfload | %s : ", + tostring (cat))) + texio.write (string.format (...)) + end + if not name then + msg ("both", 0, "load", + "Fatal error: make_loader_name (%q, %q).", + tostring (prefix), tostring (name)) + return "dummy-name" + end + name = tostring (name) + if prefix == false then + msg ("log", 9, "load", + "No prefix requested, passing module name %q unmodified.", + name) + return tostring (name) .. ".lua" + end + prefix = tostring (prefix) + msg ("log", 9, "load", + "Composing module name from constituents %s, %s.", + prefix, name) + return prefix .. "-" .. name .. ".lua" +end + +local timing_info = { + t_load = { }, + t_init = { }, +} + +local function make_loader (prefix, load_helper) + return function (name) + local t_0 = osgettimeofday () + local modname = make_loader_name (prefix, name) + --- We don’t want the stack info from inside, so just pcall(). + local ok, data = pcall (load_helper or require, modname) + local t_end = osgettimeofday () + timing_info.t_load [name] = t_end - t_0 + if not ok then + io.write "\n" + local msg = luaotfload.log and luaotfload.log.report or print + msg ("both", 0, "load", "FATAL ERROR") + msg ("both", 0, "load", " × Failed to load %q module %q.", + tostring (prefix), tostring (name)) + local lines = string.split (data, "\n\t") + if not lines then + msg ("both", 0, "load", " × Error message: %q", data) + else + msg ("both", 0, "load", " × Error message:") + for i = 1, #lines do + msg ("both", 0, "load", " × %q.", lines [i]) + end + end + io.write "\n\n" + local debug = debug + if debug then + io.write (debug.traceback()) + io.write "\n\n" + end + os.exit(-1) + end + return data + end +end + +--[[doc-- + Certain files are kept around that aren’t loaded because they are part of + the imported fontloader. In order to keep the initialization structure + intact we also provide a no-op version of the module loader that can be + called in the expected places. +--doc]]-- + +local function dummy_loader (name) + luaotfload.log.report ("log", 3, "load", + "Skipping module %q on purpose.", + name) +end + +local context_environment = setmetatable({}, {__index = _G}) +luaotfload.fontloader = context_environment +local function context_isolated_load(name) + local fullname = kpse.find_file(name, 'lua') + if not fullname then + error(string.format('Fontloader module %q could not be found.', name)) + end + return assert(loadfile(fullname, nil, context_environment))(name) +end + +local function context_loader (name, path) + luaotfload.log.report ("log", 3, "load", + "Loading module %q from Context.", + name) + local t_0 = osgettimeofday () + local modname = make_loader_name (false, name) + local modpath = modname + if path then + if lfs.isdir (path) then + luaotfload.log.report ("log", 3, "load", + "Prepending path %q.", + path) + modpath = file.join (path, modname) + else + luaotfload.log.report ("both", 0, "load", + "Non-existant path %q specified, ignoring.", + path) + end + end + local ret = context_isolated_load (modpath) + local t_end = osgettimeofday () + timing_info.t_load [name] = t_end - t_0 + + if ret ~= nil then + --- require () returns “true” upon success unless the loaded file + --- yields a non-zero exit code. This isn’t per se indicating that + --- something isn’t right, but against HH’s coding practices. We’ll + --- silently ignore this ever happening on lower log levels. + luaotfload.log.report ("log", 4, "load", + "Module %q returned %q.", modname, ret) + end + return ret +end + +local function install_loaders () + local loaders = { } + local loadmodule = make_loader "luaotfload" + loaders.luaotfload = loadmodule + loaders.fontloader = make_loader ("fontloader", context_isolated_load) + loaders.context = context_loader + loaders.ignore = dummy_loader +----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain + + function loaders.initialize (name) + local tmp = loadmodule (name) + local init = type(tmp) == "table" and tmp.init or tmp + if init and type (init) == "function" then + local t_0 = osgettimeofday () + if not init () then + logreport ("log", 0, "load", + "Failed to load module %q.", name) + return + end + local t_end = osgettimeofday () + local d_t = t_end - t_0 + logreport ("log", 4, "load", + "Module %q loaded in %g ms.", + name, d_t * 1000) + timing_info.t_init [name] = d_t + end + end + + return loaders +end + +local luaotfload_initialized = false --- prevent multiple invocations + +luaotfload.main = function () + + if luaotfload_initialized then + logreport ("log", 0, "load", + "Luaotfload initialization requested but is already \z + loaded, ignoring.") + return + end + luaotfload_initialized = true + + luaotfload.loaders = install_loaders () + local loaders = luaotfload.loaders + local loadmodule = loaders.luaotfload + local initialize = loaders.initialize + + local starttime = osgettimeofday () + + -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz + -- detection in other modules + local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') + if harfstatus then + luaotfload.harfbuzz = harfbuzz + end + + local init = loadmodule "init" --- fontloader initialization + init (function () + + logreport = luaotfload.log.report + initialize "parsers" --- fonts.conf and syntax + initialize "configuration" --- configuration options + end) + + initialize "loaders" --- Font loading; callbacks + initialize "database" --- Font management. + initialize "colors" --- Per-font colors. + + local init_resolvers = loadmodule "resolvers" --- Font lookup + init_resolvers () + + if not config.actions.reconfigure () then + logreport ("log", 0, "load", "Post-configuration hooks failed.") + end + + initialize "features" --- font request and feature handling + + if harfstatus then + loadmodule "harf-define" + loadmodule "harf-plug" + end + loadmodule "letterspace" --- extra character kerning + loadmodule "embolden" --- fake bold + loadmodule "notdef" --- missing glyph handling + loadmodule "suppress" --- suppress ligatures by adding ZWNJ + loadmodule "szss" --- missing glyph handling + initialize "auxiliary" --- additional high-level functionality + loadmodule "tounicode" + loadmodule "case" + if tex.outputmode == 0 then + loadmodule "dvi" --- allow writing fonts to DVI files + end + + luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec + + logreport ("log", 1, "main", + "initialization completed in %0.3f seconds\n", + osgettimeofday() - starttime) +----inspect (timing_info) + luaotfload_module = nil +end + +-- vim:tw=79:sw=4:ts=4:et diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty index 33e15ba7c3..d9a3397d14 100644 --- a/macros/luatex/generic/luaotfload/luaotfload.sty +++ b/macros/luatex/generic/luaotfload/luaotfload.sty @@ -39,11 +39,11 @@ \fi \ifdefined\ProvidesPackage \ProvidesPackage{luaotfload}% - [2020/09/02 v3.15 OpenType layout system] + [2020/12/31 v3.16 OpenType layout system] \fi \directlua{ if xpcall(function ()% - require('luaotfload-main')% + require('luaotfload')% end,texio.write_nl) then % local _void = luaotfload.main ()% else % diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf index 60b7e524de..5c00e2f4a6 100644 Binary files a/macros/luatex/generic/luaotfload/scripts-demo.pdf and b/macros/luatex/generic/luaotfload/scripts-demo.pdf differ diff --git a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf index 8eb287e081..fa1bda41bb 100644 Binary files a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf and b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf differ diff --git a/macros/luatex/generic/luaotfload/shaper-demo.pdf b/macros/luatex/generic/luaotfload/shaper-demo.pdf index 77a7463630..b19632bbc7 100644 Binary files a/macros/luatex/generic/luaotfload/shaper-demo.pdf and b/macros/luatex/generic/luaotfload/shaper-demo.pdf differ diff --git a/systems/doc/metapost/mpman.pdf b/systems/doc/metapost/mpman.pdf index 16e32d2ca4..1838024b4a 100644 Binary files a/systems/doc/metapost/mpman.pdf and b/systems/doc/metapost/mpman.pdf differ diff --git a/systems/doc/metapost/source-manual/mpman-app-numbersystems.tex b/systems/doc/metapost/source-manual/mpman-app-numbersystems.tex index 23d3dce7cf..4839943fb1 100644 --- a/systems/doc/metapost/source-manual/mpman-app-numbersystems.tex +++ b/systems/doc/metapost/source-manual/mpman-app-numbersystems.tex @@ -1,4 +1,4 @@ -\svnInfo $Id: mpman-app-numbersystems.tex 2023 2014-05-21 08:47:19Z stephanhennig $ +\svnInfo $Id: mpman-app-numbersystems.tex 2163 2020-12-31 19:51:53Z luigi.scarso@gmail.com $ \section{High-precision arithmetic with MetaPost} \label{hparith} @@ -21,7 +21,7 @@ Assigning a value to this variable at run-time triggers an error. The \texttt{scaled}\index{scaled?\texttt{scaled}} number system refers to 32~bit fixed-point arithmetics described in Section~\ref{datatypes}. -This is the default number system. Precision is ca. 10~decimal digits, +This is the default number system. Precision is ca.~10~decimal digits, 5 digits before and after the comma. All arithmetic operations are done in software. @@ -31,9 +31,9 @@ precision. In the internal representation, double floating-point numbers use $52+1$~bits for the mantissa, which determines precision, 11~bits for the exponent, which determines the valid range of numbers, and one bit for the sign. The smallest absolute value that can be -represented is ca. $2.2\cdot10^{-308}$, the largest value is -ca. $1.8\cdot10^{308}$. The 53~bit mantissa makes for a precision of -ca. 15 decimal digits. The smallest possible difference between two +represented is ca.~$2.2\cdot10^{-308}$, the largest value is +ca.~$1.8\cdot10^{308}$. The 53~bit mantissa makes for a precision of +ca.~15 decimal digits. The smallest possible difference between two distinct numbers in double floating-point number representation is $2^{-53} \approx 1.1\cdot10^{-16}$. The largest integer value that can be represented exactly is $2^{53}-1 \approx 9,0\cdot10^{15}$. Variable @@ -53,7 +53,7 @@ Precision is determined by an internal variable in decimal digits. Valid numbers are in the range 1 to 1000. Higher values make for better precision at the expense of performance of arithmetic operations. Default precision is 34~decimal digits -(ca. 113~bits in the mantissa). Exponent in the internal representation +(ca.~113~bits in the mantissa). Exponent in the internal representation is an integer in the range $[-9,999,999; +9,999,999]$. All arithmetic operations are done in software using the MPFR library~\cite{lib:mpfr} and are usually orders of magnitude slower than in \texttt{double} mode. diff --git a/systems/doc/metapost/source-manual/mpman-app-refman.tex b/systems/doc/metapost/source-manual/mpman-app-refman.tex index 7d301c3ce0..3581ffdd8e 100644 --- a/systems/doc/metapost/source-manual/mpman-app-refman.tex +++ b/systems/doc/metapost/source-manual/mpman-app-refman.tex @@ -472,7 +472,7 @@ $$\begin{tabular}{|l|l|l|r|l|} \pl\tt \verb|thelabel|& suffix, string, pair& picture& \pageref{Dthelab}& Text positioned as if to label a point\\\hline \pl\tt \verb|z|& suffix& pair& \pageref{Dzconv}& - The pair ${\tt x}\descr{suffix},{\tt y}\descr{suffix})$\\\hline + The pair $({\tt x}\descr{suffix},{\tt y}\descr{suffix})$\\\hline \end{tabular} $$ \index{min?\texttt{min}}\index{max?\texttt{max}}% diff --git a/systems/doc/metapost/source-manual/mpman.tex b/systems/doc/metapost/source-manual/mpman.tex index ec77468753..9df1bc3dba 100644 --- a/systems/doc/metapost/source-manual/mpman.tex +++ b/systems/doc/metapost/source-manual/mpman.tex @@ -1,4 +1,4 @@ -% $Id: mpman.tex 2139 2018-02-19 14:38:47Z luigi.scarso@gmail.com $ +% $Id: mpman.tex 2155 2019-06-02 09:39:55Z luigi.scarso@gmail.com $ % MetaPost manual, by John Hobby. License at end. \listfiles \RequirePackage{ifpdf} @@ -12,8 +12,8 @@ \fi \documentclass{article} % article is NOT the original style \usepackage[nofancy]{svninfo}% Access VCS information. -\svnInfo $Id: mpman.tex 2140 2019-06-01 14:38:47Z luigi.scarso@gmail.com $ -%\svnInfo $Id: mpman.tex 2139 2018-02-19 14:38:47Z luigi.scarso@gmail.com $ +\svnInfo $Id: mpman.tex 2155 2019-06-02 09:39:55Z luigi.scarso@gmail.com $ +%\svnInfo $Id: mpman.tex 2155 2019-06-02 09:39:55Z luigi.scarso@gmail.com $ \newcommand*{\mpversion}{2.00} \usepackage[T1]{fontenc} @@ -135,7 +135,7 @@ MetaPost is a programming language much like Knuth's \MF\footnote{\MF\ is a trademark of Addison Wesley Publishing company.}\index{metafont?\MF}~\cite{kn:c} except that it outputs -either vector graphics in the Postscript or SVG formats or bitmap +either vector graphics in the PostScript or SVG formats or bitmap graphics in the PNG format. Borrowed from \MF\ are the basic tools for creating and manipulating pictures. These include numbers, coordinate pairs, cubic splines, affine transformations, text strings, and boolean @@ -5724,7 +5724,7 @@ documents with selected applications. MetaPost graphics in the PostScript\index{PostScript} format can be easily integrated into documents prepared with \TeX\ and friends. -MetaPost's PostScript output is a low-featured dialect of the Postscript +MetaPost's PostScript output is a low-featured dialect of the PostScript language, called \emph{purified EPS}\index{EPS!purified}, which can be converted into the Portable Document Format (PDF\index{PDF}) language on-the-fly. For that reason, external MetaPost graphics can be used on diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb index b0c75afbe3..058052cf6b 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb @@ -26,11 +26,11 @@ depend container_split_src_files/1 depend frozen/0 depend minrelease/2016 depend release/2020 -depend revision/57258 +depend revision/57267 name 00texlive.image category TLCore -revision 57257 +revision 57267 shortdesc TeX Live files only in the source repository longdesc The files here are not copied by the installer and containers longdesc are not built for them; they exist only in the source @@ -40,7 +40,7 @@ longdesc IgnorePatterns in the check_files routine in tlmgr.pl augment longdesc this list. Those are not included in the source/ tarball. For longdesc information on the 00texlive prefix see longdesc 00texlive.installation(.tlpsrc) -runfiles size=13644 +runfiles size=13645 .mkisofsrc autorun.inf texmf-dist/README @@ -502,6 +502,7 @@ runfiles size=13644 tlpkg/tlpsrc/arara.tlpsrc tlpkg/tlpsrc/archaeologie.tlpsrc tlpkg/tlpsrc/archaic.tlpsrc + tlpkg/tlpsrc/archivo.tlpsrc tlpkg/tlpsrc/arcs.tlpsrc tlpkg/tlpsrc/arev.tlpsrc tlpkg/tlpsrc/arimo.tlpsrc @@ -3548,6 +3549,7 @@ runfiles size=13644 tlpkg/tlpsrc/skaknew.tlpsrc tlpkg/tlpsrc/skb.tlpsrc tlpkg/tlpsrc/skdoc.tlpsrc + tlpkg/tlpsrc/skeldoc.tlpsrc tlpkg/tlpsrc/skeycommand.tlpsrc tlpkg/tlpsrc/skeyval.tlpsrc tlpkg/tlpsrc/skills.tlpsrc @@ -21027,6 +21029,452 @@ catalogue-ctan /fonts/archaic catalogue-license lppl catalogue-topics font-archaic font-mf +name archivo +category Package +revision 57261 +shortdesc The Archivo font face with support for LaTeX and pdfLaTeX +relocated 1 +longdesc This package provides the Archivo family of fonts designed by +longdesc Omnibus-Type, with support for LaTeX and pdfLaTeX. +execute addMap ArchivZero.map +containersize 319324 +containerchecksum cb4b1c0e8a2f41eb722f60bc361e6e9fa3a36632600e08e7075dc484f4706bc06f76a4cd5f8b9ebb58cc835d8495748927ac0d39611aa9b118f38a7002aa4710 +doccontainersize 78944 +doccontainerchecksum da4361e07a99a6677c9e2ad7f477137a80b8f44170e94b00863442e6c6ce5cabae1843eb9803bcdbc3fc129b39e2c58562d05f9004c9068d09489cb10866ea61 +docfiles size=23 + RELOC/doc/fonts/archivo/Archivo-samples.pdf details="Font samples" + RELOC/doc/fonts/archivo/Archivo-samples.tex + RELOC/doc/fonts/archivo/LICENSE.TXT + RELOC/doc/fonts/archivo/README details="Readme" +runfiles size=732 + RELOC/fonts/enc/dvips/archivo/a_24xxsv.enc + RELOC/fonts/enc/dvips/archivo/a_5xld5w.enc + RELOC/fonts/enc/dvips/archivo/a_7npxgm.enc + RELOC/fonts/enc/dvips/archivo/a_fiyauo.enc + RELOC/fonts/enc/dvips/archivo/a_flfbvu.enc + RELOC/fonts/enc/dvips/archivo/a_lwgukc.enc + RELOC/fonts/enc/dvips/archivo/a_lzhlbi.enc + RELOC/fonts/enc/dvips/archivo/a_mq36jn.enc + RELOC/fonts/enc/dvips/archivo/a_owzwzj.enc + RELOC/fonts/enc/dvips/archivo/a_ttjzpe.enc + RELOC/fonts/enc/dvips/archivo/a_utd4ik.enc + RELOC/fonts/enc/dvips/archivo/a_vgwtwr.enc + RELOC/fonts/enc/dvips/archivo/a_vqpkf5.enc + RELOC/fonts/map/dvips/archivo/ArchivZero.map + RELOC/fonts/opentype/public/archivo/Archiv0-Bold.otf + RELOC/fonts/opentype/public/archivo/Archiv0-BoldItalic.otf + RELOC/fonts/opentype/public/archivo/Archiv0-Italic.otf + RELOC/fonts/opentype/public/archivo/Archiv0-Medium.otf + RELOC/fonts/opentype/public/archivo/Archiv0-MediumItalic.otf + RELOC/fonts/opentype/public/archivo/Archiv0-Regular.otf + RELOC/fonts/opentype/public/archivo/Archiv0-SemiBold.otf + RELOC/fonts/opentype/public/archivo/Archiv0-SemiBoldItalic.otf + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Bold-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-BoldItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Italic-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Medium-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-MediumItalic-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-Regular-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBold-tosf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-lf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-osf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-sup-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-sup-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-sup-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-sup-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-sup-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tlf-ts1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-ly1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-ly1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-ot1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-t1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-t1.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-ts1--base.tfm + RELOC/fonts/tfm/public/archivo/Archiv0-SemiBoldItalic-tosf-ts1.tfm + RELOC/fonts/vf/public/archivo/Archiv0-Bold-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Bold-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-BoldItalic-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Italic-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Medium-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-MediumItalic-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-Regular-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBold-tosf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-lf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-lf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-lf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-osf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-osf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-osf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-sup-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-sup-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tlf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tlf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tlf-ts1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tosf-ly1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tosf-t1.vf + RELOC/fonts/vf/public/archivo/Archiv0-SemiBoldItalic-tosf-ts1.vf + RELOC/tex/latex/archivo/Archivo.sty + RELOC/tex/latex/archivo/LY1ArchivZero-LF.fd + RELOC/tex/latex/archivo/LY1ArchivZero-OsF.fd + RELOC/tex/latex/archivo/LY1ArchivZero-Sup.fd + RELOC/tex/latex/archivo/LY1ArchivZero-TLF.fd + RELOC/tex/latex/archivo/LY1ArchivZero-TOsF.fd + RELOC/tex/latex/archivo/OT1ArchivZero-LF.fd + RELOC/tex/latex/archivo/OT1ArchivZero-OsF.fd + RELOC/tex/latex/archivo/OT1ArchivZero-Sup.fd + RELOC/tex/latex/archivo/OT1ArchivZero-TLF.fd + RELOC/tex/latex/archivo/OT1ArchivZero-TOsF.fd + RELOC/tex/latex/archivo/T1ArchivZero-LF.fd + RELOC/tex/latex/archivo/T1ArchivZero-OsF.fd + RELOC/tex/latex/archivo/T1ArchivZero-Sup.fd + RELOC/tex/latex/archivo/T1ArchivZero-TLF.fd + RELOC/tex/latex/archivo/T1ArchivZero-TOsF.fd + RELOC/tex/latex/archivo/TS1ArchivZero-LF.fd + RELOC/tex/latex/archivo/TS1ArchivZero-OsF.fd + RELOC/tex/latex/archivo/TS1ArchivZero-TLF.fd + RELOC/tex/latex/archivo/TS1ArchivZero-TOsF.fd +catalogue-contact-bugs https://github.com/ccebinger/CTAN_Archivo +catalogue-contact-development https://github.com/ccebinger/CTAN_Archivo +catalogue-contact-home https://github.com/ccebinger/CTAN_Archivo +catalogue-contact-repository https://github.com/ccebinger/CTAN_Archivo +catalogue-contact-support https://github.com/ccebinger/CTAN_Archivo +catalogue-ctan /fonts/archivo +catalogue-license ofl lppl +catalogue-topics font font-body font-serif font-proportional font-ttf font-supp font-t1enc +catalogue-version 0.0.1 + name arcs category Package revision 15878 @@ -36871,15 +37319,15 @@ catalogue-version 1.0 name biblatex-nature category Package -revision 48940 +revision 57262 shortdesc BibLaTeX support for Nature relocated 1 longdesc The bundle offers styles that allow authors to use BibLaTeX longdesc when preparing papers for submission to the journal Nature. -containersize 3272 -containerchecksum 265427460a57fa3cba846b3e7dd4fddf9639c11e223cba5e7f47da5b18ed1d348a70c29204378ab560f2eeacfdb12257c25482a1c3d9836f9025d0ddf987b511 -doccontainersize 385628 -doccontainerchecksum 9053472af9e07e4c297ce0650c7d9d20b85dfe22645652a9be49e950bc9718160433e6ffa01e5d0dec04a036425e31d4b7e6c31de9fc7553a730720fe54eb36a +containersize 3256 +containerchecksum b4b12abe904d96c9489dbdf248042ed1f1af1474921e0835027220059492f2441aace661260fa3632a65bb2c1ec0ab4e521014e63a14f7fb835293fd8191c2fe +doccontainersize 385524 +doccontainerchecksum c5169189b1225dba8631a0f7f5ceb5bdb5267888b2817716e23aa79bd4516665965b4343ed5e1a8e5099eb59ca64cea9edbd31613f7cb02f161b8ba561c6d4e5 docfiles size=100 RELOC/doc/latex/biblatex-nature/README.md details="Readme" RELOC/doc/latex/biblatex-nature/biblatex-nature.bib @@ -36889,9 +37337,9 @@ runfiles size=6 RELOC/tex/latex/biblatex-nature/nature.bbx RELOC/tex/latex/biblatex-nature/nature.cbx catalogue-ctan /macros/latex/contrib/biblatex-contrib/biblatex-nature -catalogue-license lppl1.3 +catalogue-license lppl1.3c catalogue-topics biblatex journalpub -catalogue-version 1.3c +catalogue-version 1.3d name biblatex-nejm category Package @@ -64070,7 +64518,7 @@ containerchecksum 5bd74e1a434549cf31ce31777e9a32f90baa14148e6658633945508a46dbf6 name collection-fontsextra category Collection -revision 57232 +revision 57261 shortdesc Additional fonts relocated 1 depend Asana-Math @@ -64087,6 +64535,7 @@ depend anonymouspro depend antiqua depend antt depend archaic +depend archivo depend arev depend arimo depend arvo @@ -64394,7 +64843,7 @@ depend yfonts-t1 depend yinit-otf depend zlmtt containersize 1860 -containerchecksum 9f8b815e3fb19cfa0a07e0d34d09f6d8468e035b38e3944ce37894fbdfab5663d405da1f84b66c0d2b27309e8503d48e1f37ee6696831a57ce9cf8250e9cecb9 +containerchecksum a029c987592a77b94421648fcd10d085135a6518ed1dccd085c628d2d1025b081364ab4824cf571261a20146e26ef063f61030ca33be154f9160383929a27f0e name collection-fontsrecommended category Collection @@ -65414,7 +65863,7 @@ containerchecksum 0568a3251d71fb3106fbb3961427200419ae1df22d39b5e72c608e2d94fc35 name collection-latexextra category Collection -revision 57248 +revision 57264 shortdesc LaTeX additional packages relocated 1 longdesc A very large collection of add-on packages for LaTeX. @@ -66510,6 +66959,7 @@ depend simpleinvoice depend sitem depend skb depend skdoc +depend skeldoc depend skeycommand depend skeyval depend skills @@ -66761,8 +67211,8 @@ depend ziffer depend zref depend zwgetfdate depend zwpagelayout -containersize 6236 -containerchecksum 882036a5f9a5a9257b814726f66491f4cea2537305f77abedc459da593e041e2af151d245a5b54fbdfc7f814d83bcee998f4c5d8343afd0515c2cce86ca07d04 +containersize 6232 +containerchecksum ff72fd353cdf87715cc01bab060b52f296b731aed24b412c56e5716829cf3760c86034d49df7509fdc42698796e3f3d5cdebf27e71569874335ebb07f388e33c name collection-latexrecommended category Collection @@ -128268,7 +128718,7 @@ catalogue-topics font font-body font-multilingual font-greek font-cyrillic font- name gost category Package -revision 57251 +revision 57267 shortdesc BibTeX styles to format according to GOST relocated 1 longdesc BibTeX styles to format bibliographies in English, Russian or @@ -128277,11 +128727,11 @@ longdesc 8-bit and Unicode (UTF-8) versions of each BibTeX style, in longdesc each case offering a choice of sorted and unsorted. Further, a longdesc set of three styles (which do not conform to current standards) longdesc are retained for backwards compatibility. -containersize 17272 -containerchecksum aeb5bc99764c4fefe4d173981f2b1630b1acee80a195dfb04ce65ab32c7eac3c403488b195579bace5774627d75dbd26ab4354c2575546492f8158041192b014 -doccontainersize 1766840 -doccontainerchecksum b562cc3e4f9c33bc426740fc8a953449e14423e07611cde8d59c7ed98876a04f9c10ce194ee6210484823e7a543bb4d9022ad76777199d3d9506c80b0faf9bf6 -docfiles size=1574 +containersize 17456 +containerchecksum d7e26a19b61d98aa2fd0b007e5b4d3a8193f16d1fc5be40af7657e63b9192e29aadb07128414b25b1c7fa1fa15da88463def5cec46f2a2efcfed89c42be060b8 +doccontainersize 1764668 +doccontainerchecksum 6948132245db5028832119139ac9eb0ab9c65bd565104c3edbaebff255881e97808d2454d03a83d484ff4d7548fed7fc4f7dfb85415b907c0c7d9823a1fc2f4d +docfiles size=1575 RELOC/doc/bibtex/gost/README RELOC/doc/bibtex/gost/README.md details="Readme" language="en" RELOC/doc/bibtex/gost/examples/cp1251/bib/ex01.bib @@ -128360,6 +128810,7 @@ docfiles size=1574 RELOC/doc/bibtex/gost/examples/cp1251/bib/ex74.bib RELOC/doc/bibtex/gost/examples/cp1251/bib/ex75.bib RELOC/doc/bibtex/gost/examples/cp1251/bib/ex76.bib + RELOC/doc/bibtex/gost/examples/cp1251/bib/ex77.bib RELOC/doc/bibtex/gost/examples/cp1251/gost.tex RELOC/doc/bibtex/gost/examples/cp1251/gost2003.pdf RELOC/doc/bibtex/gost/examples/cp1251/gost2003.tex @@ -128452,6 +128903,7 @@ docfiles size=1574 RELOC/doc/bibtex/gost/examples/utf8/bib/ex74.bib RELOC/doc/bibtex/gost/examples/utf8/bib/ex75.bib RELOC/doc/bibtex/gost/examples/utf8/bib/ex76.bib + RELOC/doc/bibtex/gost/examples/utf8/bib/ex77.bib RELOC/doc/bibtex/gost/examples/utf8/make-examples-on-win-utf8.cmd RELOC/doc/bibtex/gost/examples/utf8/ugost.tex RELOC/doc/bibtex/gost/examples/utf8/ugost2003.pdf @@ -128469,12 +128921,12 @@ docfiles size=1574 RELOC/doc/bibtex/gost/examples/utf8/ugost2008s.pdf RELOC/doc/bibtex/gost/examples/utf8/ugost2008s.tex RELOC/doc/bibtex/gost/gost.pdf details="Package documentation" language="en" -srccontainersize 31956 -srccontainerchecksum b817a6e3eb707d2df45debe02ddedf5b7d72c3d73790f106172e8ee41ff15aa90d2676340f1914abe2909ad3a27fb81ecbf2c7d78d9c0e8f10225a619f5ab763 +srccontainersize 32068 +srccontainerchecksum 33704ba3f239398a7d3bdf0d09a6703bfd168bfee90f613553927cae354caad1e430dcae24d681cfd67a9a60bb55a6edce151fe43e4d2c7146f7008cb48842d6 srcfiles size=43 RELOC/source/bibtex/gost/gost.dtx RELOC/source/bibtex/gost/gost.ins -runfiles size=260 +runfiles size=267 RELOC/bibtex/bst/gost/gost2003.bst RELOC/bibtex/bst/gost/gost2003s.bst RELOC/bibtex/bst/gost/gost2008.bst @@ -128497,8 +128949,8 @@ runfiles size=260 RELOC/bibtex/csf/gost/utf8cyrillic.csf catalogue-also biblatex-gost catalogue-ctan /biblio/bibtex/contrib/gost -catalogue-license lppl1.3 -catalogue-topics bibtex-sty russian +catalogue-license lppl1.3c +catalogue-topics bibtex-sty russian std-conform catalogue-version 1.2k name gothic @@ -181304,25 +181756,25 @@ catalogue-version 0.6 name luamplib category Package -revision 53904 +revision 57266 shortdesc Use LuaTeX's built-in MetaPost interpreter relocated 1 longdesc The package enables the user to specify MetaPost diagrams longdesc (which may include colour specifications from the color or longdesc xcolor packages) into a document, using LuaTeX's built-in longdesc MetaPost library. The facility is only available in PDF mode. -containersize 11692 -containerchecksum fbb99aa90563e6cce2e5e9c417f739868130f8a2dd9875fba8a44e3f92e94643f2a9446cf686f222067c5aec66e5199eb5fc134458d2a72f2fa8bc949ed51a1d -doccontainersize 152304 -doccontainerchecksum e0568e3547253f6dc9d12f927c3d7025454520ec8611ede49497f80a6354518d07eb9d300208fa4a8173b068ce65904f45c071d0fea5bfb3bfe8de1d29e6a0ec +containersize 11680 +containerchecksum 031db09bdfdc98fc7b0016c5fd3254545eff1aaeab5fb9b75dddc15550a2027f1b1c8878dbf2aad91e85b81bd83ebfcfd8ff3b0c0324d9f8d9bb25209b9bddac +doccontainersize 152328 +doccontainerchecksum a50f02149ecd45c7cac42c74b581743db01bf689bf67647886c37df5058cd1c0eb12f4ac4d7a85619cc6cab66090a523265ce4ad503c7e3fab3512934846c845 docfiles size=43 RELOC/doc/luatex/luamplib/NEWS RELOC/doc/luatex/luamplib/README details="Readme" RELOC/doc/luatex/luamplib/luamplib.pdf details="Package documentation" RELOC/doc/luatex/luamplib/test-luamplib-latex.tex RELOC/doc/luatex/luamplib/test-luamplib-plain.tex -srccontainersize 26532 -srccontainerchecksum 3a00f23c25b683b9c8949a7cb4841fa92babc470d40f756898c68fe2ed82e090cd7cca2dfaa4fa7894d7a4ea96ce5db5936ed2b1d509af118cdf039ea7a8e7a3 +srccontainersize 26536 +srccontainerchecksum 77cfe57ac556db077cc9d90fecbcf23d46a115172bbc687f9d2b902ee720eb404105ef09aa0ec7ecf6ef5785a4e11a21663568a10539f6057418c62745e2e51c srcfiles size=24 RELOC/source/luatex/luamplib/Makefile RELOC/source/luatex/luamplib/luamplib.dtx @@ -181334,7 +181786,7 @@ catalogue-contact-repository http://github.com/lualatex/luamplib catalogue-ctan /macros/luatex/generic/luamplib catalogue-license gpl2 catalogue-topics mp-use graphics-in-tex luatex -catalogue-version 2.20.5 +catalogue-version 2.20.6 name luaotfload category Package @@ -209682,15 +210134,15 @@ catalogue-version 1.2 name nomencl category Package -revision 54080 +revision 57263 shortdesc Produce lists of symbols as in nomenclature relocated 1 longdesc Produces lists of symbols using the capabilities of the longdesc MakeIndex program. -containersize 3688 -containerchecksum afc93122b5bf8dbcac2eaf61c4e90792107249cdbcea44e0067d704b35756d44c249df4e6924f1a74b68dc7ed753467a73db687b9ab38ec965a5722348b7b3c8 -doccontainersize 530908 -doccontainerchecksum 17ff56c02b4bc66cbbad73cdd05e254fafc4b44dbd45bb7e749c0e9f25a8dc3c6f4a4e82690a5dc13558b52f1dd679235cf78b15aac22825db1c7a2cf9308c48 +containersize 3776 +containerchecksum f63b053f8d95a58e2d8ec5d42177f13bdaa49f6cec710e166a96f45187b51cbe12b34c68918c0ec42b12250ecf1af80f5dbb83f4161b2d0dc94d51ccf218391b +doccontainersize 531236 +doccontainerchecksum cf29a353af0a32e41d18087d3ae9c8447d52cb0f95dabfbde01150d15637022d53a8576c362bd7489e8110cdc5dc1892159652d67e61f165f25a78b64d8e095c docfiles size=163 RELOC/doc/latex/nomencl/README details="Readme" RELOC/doc/latex/nomencl/nomencl.pdf details="Package documentation" @@ -209707,8 +210159,8 @@ docfiles size=163 RELOC/doc/latex/nomencl/sample05.pdf RELOC/doc/latex/nomencl/sample05.tex RELOC/doc/latex/nomencl/sample06.cfg -srccontainersize 18712 -srccontainerchecksum 6561f296ccef879ed95011bddc7472b1f6049e262e2ba16a996ca703aa665fb2c3f186271a1256c509fdc10db407a20acc87ad13b30edd1249a14e49bb02512a +srccontainersize 18836 +srccontainerchecksum e64dc93929ebdf9716208bc51af759003b7e3263a95d58dab5bfe740a71c966d4f51d561e4cf2d82f90bf3e081b4cb0c7a50a1e0a657d2b33b3a065a2e88a557 srcfiles size=20 RELOC/source/latex/nomencl/Makefile RELOC/source/latex/nomencl/nomencl.drv @@ -209724,7 +210176,7 @@ catalogue-contact-repository https://github.com/borisveytsman/nomencl catalogue-ctan /macros/latex/contrib/nomencl catalogue-license lppl catalogue-topics glossary -catalogue-version 5.4 +catalogue-version 5.5 name nomentbl category Package @@ -268115,6 +268567,22 @@ catalogue-license lppl1.3 catalogue-topics doc-supp class catalogue-version 1.5d +name skeldoc +category Package +revision 57264 +relocated 1 +containersize 5764 +containerchecksum a31a0fe54b6819622fbb343a32f5b17435cb7a1b8920d1ea80ec596e3f3943feee6ed071ab272281d6a8c50ab99b0ff6d7e81b9977165baf3a40c5461d46e7cf +doccontainersize 220848 +doccontainerchecksum 0fdda6193845cfca2a9b4f4d0f44a5f533c026df88789e83aa8211620d5ca846bb532ca957bc1b3c96d3998e0bb415f6d5242f82b131798558b12dd052446ed9 +docfiles size=57 + RELOC/doc/latex/skeldoc/LICENSE + RELOC/doc/latex/skeldoc/README.md + RELOC/doc/latex/skeldoc/skeldoc.pdf + RELOC/doc/latex/skeldoc/skeldoc.tex +runfiles size=6 + RELOC/tex/latex/skeldoc/skeldoc.sty + name skeycommand category Package revision 24652 @@ -292473,15 +292941,15 @@ docfiles size=591 name texlive-docindex category TLCore -revision 57250 +revision 57260 shortdesc top-level TeX Live doc.html, etc. longdesc These files are regenerated as needed, which is often, so we longdesc make them a separate package. See the tl-update-auto script for longdesc the process. containersize 388 -containerchecksum 68b944be6a943dcf2af4059a0bdec5f4e0b38aeb1fd79620da584fccd2efc872d015f25f53df1d5ceda6c65914142edc2b27b1a2d5a37bae9f75ddcb31138b23 -doccontainersize 170828 -doccontainerchecksum 42ba53aa0c342447f4bd6e660cb7c7aa13d99035851a7149535263786fdf14374ff592adfc65fec420f5edbf6638fa63f058bcfc4cbc3629edee62e7db3494d3 +containerchecksum c99296ef052fa8ac637a234f0e4f69d23f9efbefbf41ce215c15bb70c9dc811bc0b47e213c4c624f0b6b65b8c71a156144e190005a5bdc144ee9174e7b3141f9 +doccontainersize 170888 +doccontainerchecksum ec2a21e397373d4f67f8f1051a61cab20143ec10a266df981cab9049bbced6225851b4b88f2b2c610e249e0e6b25e4a740c6418ddf49a66102c25f5127f7ed81 docfiles size=339 doc.html @@ -330652,7 +331120,7 @@ catalogue-version 0.981 name xurl category Package -revision 53538 +revision 57265 shortdesc Allow URL breaks at any alphanumerical character relocated 1 longdesc This package loads url by default and defines possible URL @@ -330661,9 +331129,9 @@ longdesc - ~ ' " All arguments which are valid for url can be used and longdesc will be passed on to this package. For more information read longdesc the documentation of url itself. containersize 1612 -containerchecksum c034606febfdf397774f51f5057fb12243e5fbcd6ff8c9aa1fe60fa2643b5cdfe6c36558e5a4398e7c38c0da520ffeb53a930fda983b79c9d41fb31b74d6ad25 -doccontainersize 57924 -doccontainerchecksum 6c8833dcbec24d6b336b6dff58558ce4c38de22032f24d7510db85e987c83b2cd2089bc1a5b414ac82987bd8387dadf3456f0ca3885607285834688fafd29175 +containerchecksum 51251afe43f9b175e4afd901f10edd63bad590b0591f117d423866ed1a82e2c0ab35dee7e03250c331f8a8605f9c6ba8357e93ef0aa80d40dc03379bde24dd1c +doccontainersize 58020 +doccontainerchecksum df7e35d13f340c44813e0656c36148b92319a7099ae47eb02513d33834b642528eff2e81299aa670c2a4572e78c830d48c83b46996700e9fb568db16b84f1e57 docfiles size=18 RELOC/doc/latex/xurl/Changes RELOC/doc/latex/xurl/README.md details="Readme" @@ -330674,7 +331142,7 @@ runfiles size=2 catalogue-ctan /macros/latex/contrib/xurl catalogue-license lppl1.3 catalogue-topics verbatim -catalogue-version 0.09 +catalogue-version 0.09a name xwatermark category Package diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 index e2b368f888..6005c6fa9e 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 @@ -1 +1 @@ -632dae962af95865d7f1560772bc05c3 texlive.tlpdb +c7836317cd6b38fe3a64170f28a048a7 texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 index c2b3f1db67..d05aa9750e 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 @@ -1 +1 @@ -a85bab87e0efdc1fef2a1aecb58e2729697874eea84ea0675cb872b580a44a89f5efe1bfcea1249ac910b46c0c5ec33f45b5d1f48f9c4951ed6cd76747c9885f texlive.tlpdb +f12f87f45d4c28eaebb7c70db5ac0b842d48d4dbf1e957a454f5735bbaecbef10c321d50077bac8e5c10dac567e527f134ba5df1091d675dbe69d17daea105cb texlive.tlpdb diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc index fd3edad960..e990c7e070 100644 --- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc +++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc @@ -1,10 +1,10 @@ -----BEGIN PGP SIGNATURE----- -iQEcBAEBCgAGBQJf69CEAAoJEEzhh34ZQ4xwFQ8H/AnrJi42h1bE38xrqKtHyROX -DO+mDNOyKfCglWn66HubM7utiJHon1XmeN3ixtl3+LTY+HEl3H6rZizXCeWjqu2g -za2LmQ/7qU/OVXEjcIFLx0nOq1bfH/OceFiefjJhZ+DsC9WMsDgPQmBKE75UqC7C -CajVSoLxUUY49g9t5V+OmkEMyVstro3pwK2t00pb+Rxi5JwPRxAPspYaPxKwxU6B -WICItmVVP+fPPrX7Q9809EktT3tU2R1xIrFX4k25gpTmz8+XqZKJeV8Zx211rm4e -5JASKLpKfAVNmBMwfxVLTpgpVEmDDUg3aF0HuCRI4L/0H6cW/3axkFILKI2FVMg= -=xXE8 +iQEcBAEBCgAGBQJf7SISAAoJEEzhh34ZQ4xwaf8IAINfVguLCVPIYxTCfNuIhR8F +Goj3dZ+RmzZ2Mq2hiNqwyesOd/siBDEghluwyQUPxMSUj2RX0TG1BQ/S5gGqaXl1 ++AEpd7/acyL6Ea0CpfG+pc/X4dWK03IpMV9zSfWnI6iHjRmlE+MjeLDbgjTNzGWE +c4rumdNblX//AjEvJEYu5AFafn5oRvXnEyA7LrYwSG2L4R7H4MUtN6O7xIgUbOPU +cG4q0PUB29VfsGiktwgYytE79wTHYfrnGfAqbYBLad82ft566L6LQeoaG5SdpmV1 +BDjhK6mMxqxLew/B1gSutYMUd17mQNVisK8iLSOn581OeMMPzEIUIbjEDHpt7tw= +=tlDQ -----END PGP SIGNATURE----- diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz index 21463b1483..43f4f536b0 100644 Binary files a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz and b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz differ diff --git a/systems/win32/miktex/tm/packages/next/pr.ini b/systems/win32/miktex/tm/packages/next/pr.ini index 15da957713..f03523142f 100644 --- a/systems/win32/miktex/tm/packages/next/pr.ini +++ b/systems/win32/miktex/tm/packages/next/pr.ini @@ -1,13 +1,13 @@ [repository] -date=1609362890 +date=1609449288 lastupd=miktex-arctrl-bin-2.9 miktex-arctrl-bin-x64-2.9 miktex-asymptote-bin-2.9 miktex-asymptote-bin-x64-2.9 miktex-autosp-bin-2.9 miktex-autosp-bin-x64-2.9 miktex-axohelp-bin-2.9 miktex-axohelp-bin-x64-2.9 miktex-bibarts-bin-2.9 miktex-bibarts-bin-x64-2.9 miktex-bibtex-bin-2.9 miktex-bibtex-bin-x64-2.9 miktex-bibtex8bit-bin-2.9 miktex-bibtex8bit-bin-x64-2.9 miktex-bzip2-bin-2.9 miktex-bzip2-bin-x64-2.9 miktex-cairo-bin-2.9 miktex-cairo-bin-x64-2.9 miktex-chktex-bin-2.9 miktex-chktex-bin-x64-2.9 -lstdigest=6b0b1861fc5d5d7c635f5607c4d2e5e6 +lstdigest=717a792421ef753649b43d716c63e56f numpkg=4018 relstate=next -version=7669 +version=7670 ;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows. ;;;;-----BEGIN MIKTEX SIGNATURE----- -;;;; signature/miktex: SyhKaIdWZQ7hDrzMGi9vsvdRyVosgshxKo202VOrIX1M3KYUivTCJj2NRoE/Qr8eNMOIBtmCluy5XKX37sNABhniikWk8HkApgYzFheLj5oHh0rbenZwaRLGblD/NbmaQvFeR5U+Q3CsrAH+aMSR6JKZBSCj1OS4LH4AOyUYNnN0uWHVjgiGCTCR2KHZ1ij9PeHZdSHy+zokW4RqHEVnyeTuTfl5o22P/Cx+nL3kOxoV/8UMrLUsvJlwSpoCfTDon2kBxpJjmI+1PTj75Wb6Krqc2EXhNUCI3phpbKwdGshTQ4BpXYBemVhthrQmfqACSA57MOEvsys0b8cSoVekLg== +;;;; signature/miktex: q0mj7pjIcFl+ZbhQimKfsBhUeJ791KHSJGbqqsG8y/gtI8etx55Et+PVXYcIJs98yS3Awg8d1a8A/8hLDPMUpQT9usohq7loR9a7pGDLj7GuSIriBAqYk1vpwf8uSA3INRdM++/s1rPxaAHro1FFui/Fgq4Pdlu0M3NOTnbs3PA3eqGDxC8GvWMuWUx6Tpe5RSF23OtdzacNU290sA75kUVjaGFAI5J8Lr0fmvru5mu8TDdBxkj/dbM1LDbKue8ya9dvM+L5qlx2EKcbCYzLRek7bjr558ZwGw088yOwHVvyQ4bliZu4bpBKt1FgUixU3vKY81R1ipvv1mnbEeH1Eg== ;;;;-----END MIKTEX SIGNATURE----- diff --git a/systems/win32/miktex/tm/packages/pr.ini b/systems/win32/miktex/tm/packages/pr.ini index 06f7c64967..5b0b95f855 100644 --- a/systems/win32/miktex/tm/packages/pr.ini +++ b/systems/win32/miktex/tm/packages/pr.ini @@ -1,13 +1,13 @@ [repository] -date=1609362715 +date=1609449107 lastupd=arvo fontsize miktex-misc newtx optex pygmentex stickstoo suftesi babel beamer bookcover causets circuitikz cochineal curve2e docsurvey easyfloats fontools fontsetup gbt7714 -lstdigest=5b5a021ea1506602f087b3293f20f607 +lstdigest=91226bf773481ed54d181e53d3a56fbf numpkg=4018 relstate=stable -version=7669 +version=7670 ;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows. ;;;;-----BEGIN MIKTEX SIGNATURE----- -;;;; signature/miktex: Jh6YN9qWY4MWnL4T8cjqwaG/9CEDrp2NpoOlHBkbuYK+9x9A4h2VZ+CMJpY4ZLstYLNvchrjM3NxJZQh3s4kjZNfJdBNZE6jLwGGBuRiLxg0Z6DgNmqV+7wB/r7DnWmuA0UXHivQ0ommV/Ns9etsgBlrEJK2jJxZeS+9VRG1+Xcrpn0KpZ2VhgHRFbhrrnUY6gxiAoEKyXrjFT5AYE3qyFBjhOl6ow0eCNFhnA+aPWOahhzdbN0swHNcLvEH1SGUcHYzVjfD8cVm9BszB3pw+tGaiEoDKFa6blmvFE96EWdPGJ4uzlOCGq8DBJAhNIP7yjI55xmFeE1yriSmbTgWyQ== +;;;; signature/miktex: iJ872jxLO/7JUQWpsY8e5DcAZOuhIeypzPa9hZjBV/R/mVZbWE4n3nb4XR1k8l2jwaaWSTYqH4psreAQBL4DuO0AGYSA12aCHtn7K/DR87W4yWHVnACBJ0L0LryS/rK7qpLAhvdXJpQ2vBieSewL0jdUBb2zva9c1VrmoDkyA+tqZHcXc/7q+wKa03RzJ5LUSWLkfvVRvE1irGvGMFbg2aT1V4RarDN1JMD2mV5BOkRxzaK4D6dCXWlOwR7Tk8f4cFVnxQ4POfV2Av5N+ZqiiLx4z8a79n6uMB0X9KpMTuXwfeAXJLuB2N/V4c9XQGr5+kHjyaPYDnC4Sj5DJlgLIg== ;;;;-----END MIKTEX SIGNATURE----- diff --git a/systems/win32/w32tex/ChangeLog b/systems/win32/w32tex/ChangeLog index d0c3a7cc2c..d12b1c78c0 100644 --- a/systems/win32/w32tex/ChangeLog +++ b/systems/win32/w32tex/ChangeLog @@ -1,5 +1,14 @@ W32TeX (x86 & x64) ChangeLog +[2020/12/30] +(01) biblatex-biber.tar.xz + Update biblatex-ieee. +(02) pgfcontrib.tar.xz + Update puyotikz. Please remove + $TEXMFDIST/scripts/pythontex/puyotikz.py if it exists. +(03) ptex-w32.tar.xz + Update jlreq. + [2020/12/29] (01) ltxpkgs.tar.xz Update expkv and expkv-def. diff --git a/timestamp b/timestamp index 441f70f18b..c8c52a0c4c 100644 --- a/timestamp +++ b/timestamp @@ -2,4 +2,4 @@ # The source CTAN of this site's material: dante.ctan.org # The year-month-day-hour-minute of this site's material: -2020-12-31-02-02 +2021-01-01-02-02 -- cgit v1.2.3